The React Campaign: 1. Bootstrapping

von Patrick Bédat, 20. November 2017

After diving into React while programming a simple RSVP app for our wedding, my plans to introduce React into our company frontend stack are gaining momentum. Another reason is the fact, that we are stuck in AngularJS 1.4, because we can’t upgrade to the current version (breaking changes) due to a tight schedule. Upgrading to Angular >= 2 is not an option. (I want to spare you my ramblings – so here’s a biased but inspirational post).

To make React more approachable I decided to create an example repository. The problem with most examples is… Webpack, which is as powerful as it is complicated. So I setup a bootstrap example with just npm, jspm and the typescript compiler: https://gitlab.com/pbedat/ixts-react/tree/master/1_react-minimal-setup

Just fire it up:
git clone https://gitlab.com/pbedat/ixts-react.git && cd ixts-react/1_react-minimal-setup && npm install && npm run serve
(you will need have nodejs and git installed)

From there you can try the app (http://localhost:8080) and play with the code (it will be recompiled automatically).
Thats all for now, but I will be back with some mind blowing React sugar very soon. So stay tuned!

Integration Tests Issue 1: Docker

von Patrick Bédat, 24. Juli 2016

I think there are two types of integration tests suites:

  1. Test Suites that have become a bloated, arcane, a non maintainable collection of code wizardry with endless lines of setup code and crazy bash scripts. They test your actually very well crafted applications in a way nobody really understands. They do a good job, because they saved your asses multiple times. You hate them because the only way to make tests pass again is to comment out assertions.
  2. And the test suites written by people who created a test suite of the previous type before.

Requirements to Integration Test Suites

Integration tests are a wonderful instrument, to get as much as possible covered when you are not „test driven“ and to provide low level documentation. But what makes a good integration test suite?

  • Performance: It has to be fast. This applies to all kind of automated tests. Nothing eats up your development time, like waiting for slow tests. If you want to motivate developers to write more tests, don’t make it a burden
  • Close to production: Running a service, that depends on ghostscript on ubuntu 12.04 may give you very different results when running it on 14.04
  • Minimal invasive: So you want to test services like on a production environment. „Ok install those 100 dependencies and make sure they always match the versions like on prod. What you installed mono 4.x – oops now you have to downgrade to 2.4….“ Thinking about continuous integration, we want to have the tests running on almost naked installations. Everywhere.
  • Debuggable: Period.
  • Robustness: When you have to fire up a dozen service for testing, robustness is crucial. You don’t want to log into the build server and killing your services by hand whenever a build fails.
  • Well crafted: Invest as much love and quality into test code as into the rest of the application. Maybe even more.

Docker To The Rescue

Even though we don’t use docker for all applications on production (soon we will), they are all dockerized in our development and testing environment. Back in the days we used VMs to get our applications running locally, we were passing around gigabytes of copied VMs, because they got out of sync from time to time. We are not looking back…

The word docker still is a real „eye-brow-raiser“. Many have heard of it, knowing that is doing virtualization, but don’t really understand what’s the point about docker. Let me give you an example:

When it comes to testing in general, you always want to test on a fresh environment, because the key to predictable test execution is statelessness (docker containers are often called ephemeral). Here is the use case of „running apps on a fresh environment“ looked at from the VM and from the Docker perspective.

VM
1. Create a VM
2. Install a OS (or take snapshot, that you probably want to update)
3. Install dependencies (e.g. zip and ghostscript)
4. Make configurations
5. Deploy binaries
6. Run applications

The get a fresh environment, you have to repeat (or automate) those steps. While you can take snapshots, it will be a resource and time consuming endeavor. You can try to keep the state of the system in sync, with the actual environment, but synchronization can be a nasty thing.

Docker

  1. Create a Dockerfile
    FROM ubuntu:14.04
    MAINAINER Patrick Bédat 
    RUN apt-get update && apt-get install zip ghostscript
    
  2. Write configuration into the Dockerfile
    RUN echo "127.0.0.1 my-awesome-host" >> /etc/hosts
  3. Build an image. After an initial download, further builds will be incredebly fast (seconds)
    docker build -t my-awesome-image .

And here comes the big difference: We wont run all the applications in one docker container. We host one container per app:

docker run --volume ./bin:/opt/my-awesome-app1 my-awesome-image /opt/my-awesome-app1/app1.exe
docker run --volume ./bin:/opt/my-awesome-app2 my-awesome-image /opt/my-awesome-app2/app2.exe

Note that instead of deploying binaries, we just mapped the container directory /opt/my-awesome-appx into our hosts filesystem.
Instead of waiting for VM to boot up or a snapshot be restored, we have a container running in an instant! That is because docker does not virtualize low level stuff like hardware or an operating system. Instead it does kernel virtualization and even reuses libs and executables from the host!

container_vs_vm

Now check that Dockerfile into your repository and have your build server run those apps exactly like you did!

I hope the point, that you can spin up a complete production like environment in seconds, gives you at least clue about the power of docker. I think the hardest part to understand about docker is the ephemeral nature of containers. You don’t log into containers, they usually dont have a gui or a terminal – they just run one application and exist usually only as long as the application is running. I don’t want to dig any deeper, because docker has so much to offer and I want to focus on it’s utilization for testing.

Test Suite Setup

Back to our test suite. Before you can perform tests against real services, you need to spin them up. There are different workflows on how and when to get them running. I think the most common are:

  • Same containers per test
  • Same containers per fixture
  • Same containers per suite

The list is ordered from cleanest to the most practical and fastest solution. While starting a docker container happens in the blink of an eye, running DB setup scripts or waiting for HTTP services to be ready does not. This is our solution:

Workflow

We are using docker-compose to orchestrate the startup of a dozen containers (you know services can depend on each other). There is one docker-compose.yml file for the entire test suite. It works for us, because almost all of the services are stateless. The database is being reset with a dynamically generated list of TRUNCATE TABLE statements. And if you really need a fresh and clean container, you simply restart or recreate them. To ease things up, we created a wrapper for the docker-compose cli in C#.

This is how a docker-compose.yml looks like:

service_a:
  build: ./dir/to/service_a_dockerfile/
    link:
      - mysql
    ports:
     - "8080:80"
mysql:
  image: mysql:latest
    ports:
     - "33066:3306"

Among many other useful features, docker compose builds images and starts containers in the correct order for you.

What basically happens, when you run the nunit test suite:

  1. There is a SetupFixture, where existing containers are cleaned up first and the containers are then brought up with „docker-compose up -d“.
  2. Then we wait for all the services to be usable. E.g. we try to connect to a HTTP service and try to make a GET request.
  3. We setup the structure of the database

Then in each TestFixtureSetup or Setup, which runs either before the tests in a fixture or before each test, we truncate the whole database. Depending on how the fixture is structured, we setup a scenario in the setup or in the tests (or in both actually).

Usually you want to run tests, while you are developing. When you are developing, the services are usually running. But how can you run a HTTP service listening to port 80 run twice on the same machine, so that your test suite can talk to it? You can’t. Luckily docker allows you to remap the ports exposed by the containers, to different ports on their hosts. Hence you can run the service with the same configuration in your tests by simpliy remapping them.

Gotchas

In the first version of the test suite all exposed ports were mapped to a „test suite port“:

service_a:
  ports:
      - "8080:80"
mysql:
  ports:
      - "33066:3306"

This was very practicable while debugging, because when you halted the test after the debug, you knew, that you would be able to connect to the database with port 33066 to check, wether the scenario was correctly setup. But it also led to problems, when the suite was executed on the build server on different branches. On the one hand, because the tests couldn’t be executed in parallel (ports were already occupied) and on the other because when the test run on one branch crashed, it left services running an therefore left the ports occupied.

Our solution was to template the docker-compose file:

service_a:
  ports:
      - {{ ports.service_a }}
mysql:
  ports:
     - {{ ports.mysql }}

Now it was possible to map the ports in the development environment („8080:80“) and simply expose them on the build server („80“). When you expose ports in docker, which means you make the port accessable by the host, docker maps a random free port from the host.
But how do the clients in the integration tests get informed about how the port was mapped? Luckily docker-compose offers a „port“ command:

docker-compose port mysql
0.0.0.0:32673 -> 3306

After integrating this command to the docker-compose wrapper and tieing the clients to it, robustness of our tests multiplied.

Conclusion

Having a test suite which tests against the services as if they are running in production is a huge benefit. Making it easily executable and debuggable for developers is priceless. But it wasn’t for free. It was a long journey that beared many lessons, with a build server often remaining red for days (the team consists of 1.5 people…). But damn it was absolutely worth it.

Finally TypeScript

von Patrick Bédat, 17. Juni 2016

I’ve started my life as a developer some 14 years ago with PHP. When I started my career as a profressional developer three years later, I got in touch with statically typed languages and it felt like a rebirth. Intellisense, code completion and all the other utilities multiplied my overall hacking performance.

I was a web developer from the very beginning and when AJAX hit the mainstream, I was again confronted with a dynamic language.
But this time it was different: This time I loved working with a dynamic language. I think it’s because you can get things working incredebly fast – no type definitions, no mapping no adaption required, and the heavy lifting logic resided on the statically typed server code.

I still love JavaScript and I still feel very productive when bending it to my will. But… problems arise, when other developers join in on a former solo project, or you have to debug/extend code, that is really old.

Hacking and Programming

My definition of hacking is:
To write a minimum amount of code with acceptable quality, that is required to fulfill a requirement. Acceptable means: Structured, decoupled and easy to refactor or replace.

When you write a lot of JavaScript this way, you are automatically building a noteable amount of technical debt. First and foremost, because it is not documented. A good JavaScript library is only as good as it’s documentation. Some might argue, that good code documents itself. Tell this your coworker, who was busy programming Delphi software for the desktop…

And programming…
is everything else above that (There’s a lot good lecture about software craftmanship and quality!)
In the case of JavaScript I think of using prototypes, manual type checking, a solid documentation, unit tests, …

But even when you program JavaScript professionally and disciplined, you don’t get the goodies of a statically typed language!

Epiphany

I always believed, that switching to a statically typed language, that compiles to JavaScript, would be damn awesome… when there would be tools, that support it. But whenever I thought about introducing it in the company, the argument, that JavaScript is just good enough and the effort to establish such a big change would cost too much, weighed more.

But then some events changed my mind:

  • I witnessed how hard it was for new team members to work with the existing code. Not being able to browse the code by reference or through code completion is a serious handicap (without docs)
  • I’ve successfully introduced es6. Everybody was suddenly able to write es5 and es6 code side by side. TypeScript is like a static version of es6.
  • Angular 2.0 was completely written in TypeScript
  • There is a official TypeScript Package for the Atom Editor

On a saturday I was commited to spend the evening with integrating TypeScript in a new module of a project. It didn’t even took me an hour. I was thrilled. Writing type safe code on the client side doesn’t only scale – it rocks!

Working with Atom

TypeScript has an official Atom Packge: apm install typescript

To setup your TypeScript environment you should create a tsconfig.json (https://www.typescriptlang.org/docs/handbook/tsconfig-json.html) in the root of your project.

Mine looks like this:

{
"compileOnSave": false,
"compilerOptions": {
    "module": "commonjs",
    "noImplicitAny": true,
    "removeComments": true,
    "preserveConstEnums": true
    }
}

TypeScript allows you to go dynamic whenever you want. When you specify „noImplicitAny: true“ you have to type your dynamic with the „any“ type, which is useful, because in JavaScript you aren’t used to define types at all.

So I wrote a class:

Oh it feels so good 😀

So I want to integrate the service to my angular 1.x application. What? You say angular 1.x is not written in TypeScript? Embrace Typings!

atom2

You can write so called definition types in TypeScript, to program against typesafe interfaces of your untyped JavaScript sources. Typings is a package manager for TypeScript definitions!

Once installed (npm install -g typings) you can search for definitions (e.g. typings search jQuery) and install them (typings install –global jQuery –save-dev). This is how a definition file looks:

2016-06-17 16_10_30-Clipboard

Typings will save all the definitions in the „typings“ folder and persist your installed dependencies in a typings.json. All definitions are referenced in the typings/index.d.ts file, making them easily accessable in your code:

reference

Gulp Integration

I wanted the integration of TypeScript to be as smooth as possible. So sneaky, that other members of the team won’t even notice, that they are able to write TypeScript side by side with existing code.

This is the updated gulp task:

gulp

„ts“ refers to ts = require(„gulp-typescript“)

And that’s it basically.

Conclusion

I can’t wait to write more TypeScript. So many new opprtunities, like generating definitions from our RAML spec or from C# classes… The opportunity to upgrade our codebase to a whole new level of quality.

via GIPHY

Dealing with Azure’s StorageException: Object reference not set… using mono

von Patrick Bédat, 17. April 2016

TL;DR

This article will show you
– how to utilize docker to make a bug reproducible
– how to solve the problems with the Azure Storage Client library

The bug

When our client told me we had to export some files to the Azure Storage of some of his clients I thought: Awesome! I finally get in touch with Azure. Getting in touch with cloud services is almost everytime a good chance to get some new impressions on how to tailor APIs for the web. But it turned out different this time…

So I added the WindowsAzure.Storage package from NuGet and was thrilled how easy the implementation was:

var account = new CloudStorageAccount (new StorageCredentials (accountName, accountKey), true);

var blobClient = account.CreateCloudBlobClient();

var container = blobClient.GetContainerReference(containerId);
container.CreateIfNotExists();

var blob = container.GetBlockBlobReference(Path.GetFileName(file));
blob.UploadFromFile (file);

Charming isn’t it? And it was until files got bigger. When working for Media Carrier we are often pushing gigabytes of data over the wire and that’s where the problem started:

Microsoft.WindowsAzure.Storage.StorageException: Object reference not set to an instance of an object
---> System.NullReferenceException: Object reference not set to an instance of an object
  at System.Net.WebConnectionStream.EndRead (IAsyncResult r) <0x41fc7860 + 0x0009e> in <filename unknown>:0 
  at Microsoft.WindowsAzure.Storage.Core.ByteCountingStream.EndRead (IAsyncResult asyncResult) <0x41fbc1c0 + 0x00024> in <filename unknown>:0 
  at Microsoft.WindowsAzure.Storage.Core.Util.AsyncStreamCopier`1[T].ProcessEndRead () <0x41fd7f10 + 0x0003b> in <filename unknown>:0 
  at Microsoft.WindowsAzure.Storage.Core.Util.AsyncStreamCopier`1[T].EndOperation (IAsyncResult res) <0x41fd71c0 + 0x00067> in <filename unknown>:0 
  at Microsoft.WindowsAzure.Storage.Core.Util.AsyncStreamCopier`1[T].EndOpWithCatch (IAsyncResult res) <0x41fd6e80 + 0x00073> in <filename unknown>:0 
  --- End of inner exception stack trace ---
  at Microsoft.WindowsAzure.Storage.Blob.BlobWriteStream.Flush () <0x41fdd180 + 0x0007b> in <filename unknown>:0 
  at Microsoft.WindowsAzure.Storage.Blob.BlobWriteStream.Commit () <0x41fdcf40 + 0x00023> in <filename unknown>:0 
  at Microsoft.WindowsAzure.Storage.Blob.BlobWriteStream.Dispose (Boolean disposing) <0x41fdced0 + 0x00043> in <filename unknown>:0 
  at System.IO.Stream.Close () <0x7f1e247c53d0 + 0x00019> in <filename unknown>:0 
  at System.IO.Stream.Dispose () <0x7f1e247c5400 + 0x00013> in <filename unknown>:0 
  at Microsoft.WindowsAzure.Storage.Blob.CloudBlockBlob.UploadFromStreamHelper (System.IO.Stream source, Nullable`1 length, Microsoft.WindowsAzure.Storage.AccessCondition accessCondition, Microsoft.WindowsAzure.Storage.Blob.BlobRequestOptions options, Microsoft.WindowsAzure.Storage.OperationContext operationContext) <0x41fc9e10 + 0x009e0> in <filename unknown>:0 
  at Microsoft.WindowsAzure.Storage.Blob.CloudBlockBlob.UploadFromStream (System.IO.Stream source, Microsoft.WindowsAzure.Storage.AccessCondition accessCondition, Microsoft.WindowsAzure.Storage.Blob.BlobRequestOptions options, Microsoft.WindowsAzure.Storage.OperationContext operationContext) <0x41fc9db0 + 0x0004b> in <filename unknown>:0 
  at Microsoft.WindowsAzure.Storage.Blob.CloudBlockBlob.UploadFromFile (System.String path, Microsoft.WindowsAzure.Storage.AccessCondition accessCondition, Microsoft.WindowsAzure.Storage.Blob.BlobRequestOptions options, Microsoft.WindowsAzure.Storage.OperationContext operationContext) <0x41fc9cc0 + 0x00097> in <filename unknown>:0 
  at windowsstoragebug.MainClass.Main (System.String[] args) <0x41f1cd60 + 0x004f0> in <filename unknown>:0 
Request Information
RequestID:c4dedc47-0001-0038-734d-962acc000000
RequestDate:Thu, 14 Apr 2016 12:56:26 GMT
StatusMessage:Created

And my first thought was: „What did I do wrong?“. So I began messing around with the client settings:

blobClient.DefaultRequestOptions.ServerTimeout = new TimeSpan (1, 0, 0);
blobClient.DefaultRequestOptions.MaximumExecutionTime = new TimeSpan (1, 0, 0);
blobClient.DefaultRequestOptions.SingleBlobUploadThresholdInBytes = 67108864; //64M

Nock luck. So I googled: https://github.com/Azure/azure-storage-net/issues/202. It is a similar issue, but the proposed workarounds didn’t help.
It was time to dive a bit deeper into the Azure Storage service. How does it work?

Azure Storage and PutBlock

Azure storage (similar to S3 in AWS) can be used to store files. The files are stored as blobs – block blobs in this case. Block blobs are organized in containers (would be buckets in S3).
You can either upload a BlockBlob in a single transaction – when the block blob is < 64M, or upload the blob separated in blocks, each < 4M with a maximum of 50000 blocks. Each block gets a unique block id in natural order. When all blocks have been transmitted to azure you commit the transaction by sending the whole list of block ids.

See https://msdn.microsoft.com/de-de/library/azure/ee691974.aspx

I felt lucky, when I saw, that the azure client offered a PutBlock and a PutBlockList method. So I tried to upload the file in chunks:

using(var stream = File.OpenRead(file))
{
    int position = 0;
    const int BLOCK_SIZE = 4 * 1024 * 1024;
    int currentBlockSize = BLOCK_SIZE;

    var blockIds = new List<string>();
    var blockId = 0;

    while(currentBlockSize == BLOCK_SIZE)
    {
        if ((position + currentBlockSize) > stream.Length)
            currentBlockSize = (int)stream.Length - position;

        if(currentBlockSize == 0)
            continue;

        byte[] chunk = new byte[currentBlockSize];
        stream.Read (chunk, 0, currentBlockSize);

        var base64BlockId = Convert.ToBase64String(System.Text.Encoding.Default.GetBytes(blockId.ToString("d5")));

        using(var memoryStream = new MemoryStream(chunk))
        {
            memoryStream.Position = 0;                  
            blob.PutBlock(base64BlockId, memoryStream, null);
        }

        blockIds.Add(base64BlockId);

        position += currentBlockSize;
        blockId++;

    }

    blob.PutBlockList(blockIds);
}

I ran it on my machine and started to burst into dancing. Not for long though… After deploying it, uploading suddenly stuck. Then on my maching (and later on the staging server) it suddenly gave me those lines:

_wapi_handle_ref: Attempting to ref unused handle 0x4af
_wapi_handle_unref_full: Attempting to unref unused handle 0x4af

which means that something is very very wrong…

Challenge accepted

When a 3rd party library isn’t working correctly, I’m usually trying to root out possible errors on my side. So after 2 a.m. I did some funny things with memory streams, that I really don’t want to show you. So after my PutBlock experiment didn’t work out my motivation started to multiply. I cannot rest when some 3rd party library, which is supposed to just work, simply doesn’t bend to my will.

My next plan was to implement parts of the storage client against the azure REST api.

Being a proud and arrogant developer, I believed, that I could hack that WebRequest code for azure together in minutes… Behold the Authorization header. What a pain in the ass seriously. Just take a look at this: https://msdn.microsoft.com/de-de/library/azure/dd179428.aspx

Then I came across this beatiful article.

With the help of the article above I was finally able to write my own implementation of PutBlock (I snatched CreateRESTRequest from the article above):

var request = CreateRESTRequest ("PUT", $"{container.Name}/{blobId}?comp=block&blockid={base64BlockId}", chunk);    

var response = request.GetResponse () as HttpWebResponse;

using (var responseStream = new StreamReader(response.GetResponseStream ()))
{
    var output = responseStream.ReadToEnd ();
    if (!string.IsNullOrEmpty (output))
        yield return output;
}

AND IT WORKED LIKE A CHARM. And still does.

Making the bug reproducible

The journey doesn’t end here.

The azure storage lib is open source and whenever you are using open source software you should give something back from time to time. Either through contributions, money or by being a good bug reporter.
Filing an issue on github is easy, but if you want to have it fixed, make sure it is easily reproducible. This saves a lot of time for the hard working open source contributors.

So how do we get there? The bug happened on my Ubuntu linux 14.04 running mono Stable 4.2.3.4/832de4b. Telling somebody to setup a VM, checkout my sample code, compile it and run it, would be a lot to ask.
That’s where Docker comes into play.

To run the desired environment, we have to write a Dockerfile:

# Define the base image
FROM ubuntu:14.04
MAINTAINER Patrick Bédat <patrick.bedat@ixts.de>

# Add the mono sources
RUN apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF
RUN echo "deb http://download.mono-project.com/repo/debian wheezy main" | tee /etc/apt/sources.list.d/mono-xamarin.list

# Install mono and git
RUN apt-get update && \
    apt-get install -y \
    git mono-complete

RUN mozroots --import --sync

# Clone the sample project and build it
RUN git clone git://github.com/pbedat/azure-mono-bug.git && \
    cd azure-mono-bug && \
    mono NuGet.exe restore && \
    xbuild azure-storage-bug.sln

# This tells docker what to do when we run this image
ENTRYPOINT ["mono", "/azure-mono-bug/azure-storage-bug/bin/Debug/azure-storage-bug.exe"]

From this dockerfile you’re able to build an image:

docker build -t azure-mono-bug ./azure-mono-bug

Then you can run containers based on this image

docker run azure-mono-bug <account-name> <account-key>

The application then
– creates a 500 MB file
– tries to upload it with UploadFromFile to azure
– tries again with the PutBlock method

Conclusion

I’ve pushed the image to the docker hub. Now anybody using docker, can run the sample app by typing

pbedat/azure-mono-bug <account-name> <account-key>

Nuff said.

Best Practise: Shared Code in PHP

von Patrick Bédat, 14. November 2014

Die Verwaltung von Shared Code in PHP war mir schon immer ein Dorn im Auge… Zum Glück gibt es mittlerweile Composer. Ein vernünftiges Package Management System à la NPM, bower, NuGet und Konsorten. Doch wie ist das mit eigenen Bibliotheken, die in anderen Projekten wiederverwendet werden sollen? Als ich vor kurzem, nach Jahren der PHP Abstinenz, ein völlig desolates PHP Projekt „retten“ sollte, habe ich mir diese Frage erneut gestellt.

In der Steinzeit

Da wo ich her kam, aus der C# Welt, reicht es, eine Bibliothek einzubinden, den gewünschten Namespace der gewünschten Klasse zu importieren und voilà – man kann diese Klasse dann verwenden.

In einer Skript Sprache wie PHP ist es damit nicht getan. Nicht nur, dass es bis vor kurzem noch gar keine Namespaces gab, nein um eine Klasse zu nutzen, muss man die Datei, die sie definiert, importieren:

// Foo.php
require "my/other/lib/Bar.php";
class Foo {
  public function __construct(Bar $bar){ }
}
// Bar.php
class Bar {
}

Das Problem mit dem require ist: Die Pfade dürfen sich nicht ändern. D.h. die verwendeten Bibliotheken, müssen immer am gleichen Ort eingebundenen werden.

Dieses Problem wurde irgendwann durch die magische PHP Funktion __autoload angegangen. Wird diese Funktion implementiert, wird sie aufgerufen, sobald eine Klasse verwendet wird, die noch nicht geladen wurde.

Beispiel:

function __autoload ( string $class ) {
  require "my/other/lib/" . $class . ".php";
}
new Foo();

Da wir nun unsere Klassen nicht in einem Ordner, sondern so wie in der C# Welt in einer Ordnerstruktur ablegen, die quasi Namespaces entspricht, wollte ich mich nicht lange mit __autoload herumschlagen und bin einen pragmatischeren Weg gegangen. Ich habe schlicht und einfach in der Eintrittsdatei (index.php) alle PHP-Dateien aus den zur Verfügung stehenden Ordnerstruktur geladen. Fertig.

Die Arbeit mit Composer

Ungefähr das erste, was ich zu beginn des Projekts unternommen habe, war die Suche nach einem Package System und ich wurde fündig.

Brauche ich beispielsweise PHPUnit in einem Projekt:

php composer.phar require anahkiasen/underscore-php

Composer läd dann das Paket in den Ordner vendor und updated seine autload.php, die ich in meine PHP App einbinde:

//index.php
require "vendor/autoload.php";
use Underscore\Types\Arrays;
$arr = array(1, 2, 3);
print_r(Arrays::each($arr, function($val){
  return $val + 1;
}));
// prints: 2, 3, 4

Ganz recht: Man muss nur noch Typen über ihren vollqualifizierten Namespace einbinden (use) und die autoload.php von Composer erledigt den Rest!

An einem Punkt im Projekt, wo ich anfing Use Cases in eigene Projekte auszulagern, erschien mir mein bisheriges Vorgehen als rückständig und nicht mehr praktikabel und ich dachte mir: Irgendwie muss man doch diesen tollen Composer Autoloader für sich gefügig machen können! Und ja – man kann =)

Wenn man composer verwendet, wird eine Konfigurationsdatei angelegt. In dieser composer.json, kann man auf eigene Namespaces verweisen:

{
  "require": {
    "monolog/monolog": "1.2.*"
  },
  "autoload": {
    "psr-0": {
      "your-namespace": "deps/your-namespace"
    }
  }
}

PSR-0 gibt an dieser Stelle nur an, welcher autoloading Standard verwendet wird. PSR-0 erschien mir völlig ausreichend. Nachdem die composer.json richtig konfiguriert ist, muss man den autloader von composer neu erzeugen:

php composer.phar install

Wird nun ein Build meines Projekts angestoßen, werden zunächst die abhängigen Projekte gebaut. Die abhängigen Builds, werden dann wiederum im Build-Ordner des zu bauenden Projekts im Ordner deps/ abgelegt.

Jetzt können auch eigene Klassen, die mit Namespaces ausgestattet werden, über den Autoloader von Composer dynamisch geladen werden!

Dissecting Authentication from a Big Fat Angular Application

von Patrick Bédat, 6. Juli 2014

We recently released a „big fat“ (far beyond 10k LOC)  web application, with a front end purely written in javascript. Since it was the first big js only web app we wrote, it’s time to recap and share our lessons learned.

What I want to talk about right now, is how to treat authentication (based on cookies and http basic-auth) as what it really is: an aspect. I am absolutely sure everyone of us once made the mistake of weaving a cross functional aspect, like authentication, authorization or logging into parts of the application where they don’t belong, thus making it less readable and less testable.

Well we did not make this mistake. We put all the authentication stuff to a shared angular module and connected it with restangular in the config() section of our app. What really went wrong was the dependency between authorization and authentication in the routing module (we are using ui-router).

TL;DR: Move authentication and the rest of your app in separate apps, that coexist on one page – it’s cleaner.

Let me give you a simple example:

First Come First Served

You have the following nested state in your application:

Refreshing your browser, when you are in state „wf.employee.salary“, will cause you some trouble: You have to make sure, that your app is already authenticated, before you resolve the „employee“, otherwise the authorization will throw a 403 at you.

Of course there are many ways to overcome this. One way is to resolve the login process in the root state and reference it as a dependency, where you resolve authentication sensitive data:

Even then you would have to handle with a not authenticated client in an untransparent way. You know – redirect to a login, save the requested url, and so on…

A Clean Cut

My new approach is to fully segregate the whole login process from the rest of the application.

This is my recipe:

Have two applications on your site: One that handles authentication (bootstrapper would be a convenient name) and your main application. The „bootstrapper“ will handle authentication and bootstrap the main app, once authentication suceeded.

Move your authentication api to the bootstrapping application. A naive implementation may look like this:

In this example I initialize the authentication in the xsLoginForm directive. This is also the place, where I handle the bootstrap of the main application:

You could also .configure() your HTTP-Client with the required authentication headers, before you bootstrap your main app.

Fresher Refreshing

Now let’s take a look to back to what caused us trouble in the first place: Refreshing the page. Instead of a dependency stricken login process, the main app now does not even care about authentication. After our bootstrapping app has handled all it’s authentication needs and the main app is loaded, the ui-router will kick in, examine the url and will nicely resolve the state it held, before the refresh.

 

 

Angular.js für Azubis

von Patrick Bédat, 9. März 2014

Angular zu erlernen ist aufgrund der steilen Lernkurve auch für erfahrene Entwickler keine einfache Aufgabe.
Für Auszubildende ist der Umgang mit angular gleich doppelt schwierig: Steile Lernkurve gepaart mit absoluter Freiheit funktioniert zwar,
führt bei Code Reviews aber zu hoher Frustration.

So ergeht es auch gerade unserem Auszubildenen Michael. Nicht nur, dass er sich im ersten Lehrjahr befindet, nein auch Patterns, Paradigmen und Datenstrukturen sind ihm völlig Fremd. Deshalb verstreut er auch nur zu recht die Geschäftslogik munter zwischen Controllern und allen anderen Komponenten.

Ich habe selbst immer wieder erlebt, welche Wunder die Lektüre von Quellcode anderer Entwickler wirken kann und möchte mit dieser gebloggten Coding-Session meinem Azubi und hoffentlich auch anderen Einsteigern eine kleine Hilfestellung bieten, angular.js Apps richtig zu strukturieren.

Ausgangssituation

Michael soll ein Projekt in angular.js umsetzen. Wir lassen ihn dabei zunächst so viel Geschäftslogik, wie möglich, auf dem Client umsetzen, damit er sich nicht um weitere Technologien Gedanken machen muss. Ein Framework ermöglicht es ihm Datensätze in CRUD Manier zu speichern, zu lesen und zu löschen.

Momentan sieht das grobe Datenmodell der Anwendung so aus:

UML

Michael sollte dafür sorgen, dass die Testfälle eines Projekts als Tests einem Test-Cycle zugeordnet werden können:

screen1

Die Testfälle zur Linken können über einen Pfeil-Button als Test dem aktuellen Test-Cycle zugeordnet werden. Diese Tests können ebenfalls über einen Pfeilbutton wieder wieder aus dem Test-Cycle entfernt werden.

Template

Werfen wir zunächst mal einen Blick auf das Template:


— Was soll ich groß dazu sagen? Nichts besonderes dabei – nur standard Direktiven und keine Zauberei.

Controller

Bei Initialisierung wird zunächst mit dem GetCycle Service ein Test-Cycle abgerufen. Anhand der Tests im Test-Cycle werden die verfügbaren Testfälle dem $scope zugeordnet. —

Der Controller vermittelt zwischen dem Template und dem Model mit Hilfe folgender Schnittstelle:

  • AssignTestcase
    Weist dem Cycle den aktuell selektierten Testfall zu
  • Event: cycle:test:added
    Wird ein Test dem Cycle hinzugefügt, wird dieser Event ausgelöst.  Der Controller entfernt daraufhin den selektierten Testfall aus der Liste der zur Verfügung stehenden Testfälle
  • Event: cycle:test:remove
    Wird ein Test wieder aus dem Cycle entfernt wird dieser Event ausgelöst. Der Controller fügt dann den Testcase, der dem Test zugordnet ist, wieder der Liste der zur Verfügung stehenden Testfälle hinzu.
  • Save
    Speichert die Änderungen am Cycle ab

Models

Die Models sorgen dafür, dass wir unsere Daten mit Respekt behandeln. Sie bieten koordinierte Zugriffe auf unsere Testfälle, Tests, Cylces und sorgen z.B. für die korrekte Erstellung von Tests. Häufig verwenden Models den $rootScope dazu um Ereignisse abzusetzen, auf die Controller wiederum reagieren können.

SelectableCollection


— Mit dieser Collection kann jeweils immer ein Item (z.B. Tests oder Testfälle) selektiert werden dann entfernt werden. Nachdem ein Item entfernt wurde, wird das nächste in der Liste selektiert. Beim hinzufügen und entfernen setzt diese Collection außerdem Events in den $rootScope ab.

CycleModel

Dieses Model nutzt auch die SelectableCollection, um die Tests zu verwalten. Mit dem Model können auch Tests erstellt werden. Diese werden hier vereinfacht durch das zuordnen eines Testfalls erzeugt. —

Services

In den Services befindet sich Geschäftslogik, die sich weniger mit Datenstrukturen und Zuständen beschäftigt. Da wird beispielsweise mit anderen APIs oder dem Backend kommuniziert, es werden Daten transformiert oder Models instanziert.

GetCycle

Dieser Service ruft den gewünschten Cylce, alle Tests und Testfälle aus dem Backend ab. Danach wird der Cycle mit den zugeordneten Tests ausgestattet und jedem Test wird sein referenzierter Testfall zugeordnet.

Diese komische Konstruktion mit dem „_“. Das gehört zu einem meiner absoluten Lieblings-Frameworks: Underscore


 GetTestcasesAvailableToCycle

Die Testfälle, die dem Cycle bereits zugeordnet wurden, sollen nicht für den Cycle zur Verfügung stehen: —

GetTestcasesByProject

Wie der Name schon sagt:



 

Zusammenfassung

Ich hoffe ich konnte mit dieser kleiner Coding-Session ein paar Aha-Effekte bei euch generieren. Den gesamten ausführbaren (z.B. cd build/ && xsp) Code findet ihr übrigends hier:

https://github.com/pbedat/xAmine.explained

 

A Fairy Tale in 100 Lines of Code

von Patrick Bédat, 27. Januar 2014

Für meine IHK AdA Prüfung habe ich mir als Thema für die mündliche Prüfung meinen Lieblingsalgorithmus ausgesucht: Die Breitensuche.

Für ein anschauliches Beispiel lief es auf folgende Problemstellung hinaus:

 

Wenn die grünen Punkte überquerbares Grasland und die blauen Punkte unüberwindbare Seen sind, kann der Held die Prinzessin retten? Muss er dazu erst einen Brückentroll erschlagen? All diese Fragen kann die Breitensuche beantworten!

Das folgende Programm erstellt ein zufälliges „Königreich“ und ermittelt, ob der Held sein Ziel erreicht oder kläglich scheitert:

CWindowssystem32cmd

 

Viel Spaß mit dem Quelltext (CoffeeScript ausgeführt in node.js):

tales_of_dfs

Database Continuous Integration – The iXTS way?

von Alois Flammensboeck, 22. August 2013

DB_CI

Neue Projekte bedeuten immer auch neue Herausforderungen. Die Aktuelle lautet, dass bei zukünftigen Projekten nun auch die Datenbank mit in der Continuous Integration Toolchain berücksichtigt werden soll. Da es an einem Freitag  bei einem kollegialen Mittagessen zu wirren Diskussionen kam wie diese Challenge gemeistert werden kann, möchte ich das hier noch einmal konsolidieren.

Zuerst einmal müssen natürlich die Anforderungen geklärt werden, die wir an unsere DBCI haben:

  • Änderungen am Datenbankschema sollen in Versionsverwaltung erfasst werden
  • Konkurrierende Veränderungen am DB-Schema müssen erkannt werden
  • Der Build Server soll Datenbank-Updates automatisch ausführen/testen können
  • Die Daten sollen bei einem Datenbank Update nicht verloren gehen, sondern ggf. migriert werden
  • Der Gesamtprozess soll unabhängig vom verwendeten DBMS sein
  • Der Gesamtprozess soll möglichst bei Projektstart schon eingehalten/durchgeführt werden können

Zusätzlich standen noch folgende Anforderungen für ein aktuelles Projekt mit im Raum:

  • Die Datenbasis soll jederzeit zum Zwecke von Backup und Archivierung exportiert werden können
  • Die so erzeugten Exports sollen jederzeit in die Software einer Version größer oder gleich der Version mit der exportiert wurde wieder importiert werden können

Bezüglich Versionierung waren sich die Diskutierenden recht schnell einig. Vor kurzem haben wir beschlossen die Software Dezign for Databases für die Modellierung von Datenbanken einzusetzen. Diese Software speichert ein Datenbankmodell in einer XML-Projekt-Datei und diese Projektdatei kann dann in die Versionsverwaltung aufgenommen werden. Daraus ergibt sich unter der Voraussetzung, dass DB-Modell-Änderungen nur noch in diesen Datenbankprojekt durchgeführt werden die Erfüllung der ersten beiden Anforderungen:

okÄnderungen am Datenbankschema sollen in Versionsverwaltung erfasst werden
okKonkurrierende Veränderungen am DB-Schema müssen erkannt werden

Für die Anforderung, dass der Build-Server die Updates automatisch ausführen und testen können soll hat man zumindest schon mal das erfüllt, dass die Datenbank in der jeweiligen Version des Trunks erzeugt werden kann.

Jetzt wird es allerdings schwierig. Zur Diskussion standen folgende Möglichkeiten

Methode 1: SQL-Update-Scripts welche vom Build-Server ausgeführt werden können

Der erste Vorschlag war, dass die Entwickler dafür zuständig sind, dass zu jedem Zeitpunkt die nötigen Update Scripts im Repository sind um die Datenbank auf die aktuelle Version zu bringen. Zum besseren Verständnis ein kleines Beispiel:

Angenommen Version 1 einer Datenbank ist aktuell im Trunk. Die Datenbank enthält eine Tabelle mit Metadaten welche unter anderem auch die Versionsnummer in diesem Fall 1 enthält. Ein Entwickler möchte gerne eine weitere Tabelle zur Datenbank hinzufügen. Wie geht er vor:

  1. Update der aktuellen Workingcopy
  2. Öffnen des Dezign for Databases Projekts
  3. Sicherstellen, dass die aktuelle Version 1 auch als Version in Dezign angelegt ist
  4. Hinzufügen der Tabelle im Dezign Projekt
  5. Export des SQL-Update-Scripts aus Dezign und Ablage des Scripts in einem vordefinierten Verzeichnis mit vordefiniertem Dateinamen-Schema (z.B. Update-2.sql)
  6. Test des Update Scripts in der eigenen Datenbank und ggf. so lange Anpassungen bis es passt und die erforderlichen Migrationen durchgeführt werden
  7. Anpassen des Quellcodes, solange bis dieser wieder zum neuen DB-Schema passt
  8. Einchecken des Dezign Projekts und des Update Scripts

Was passiert nach dem Check-In?

Angenommen es existiert eine Datenbank in Version 1, welche vom Build Server auf die aktuelle Version gebracht werden soll. Der Build-Server checkt die aktuelle Version aus und führt dann ein DB-Update-Tool aus, welches folgende Schritte durchführt:

  1. Es liest die aktuelle Version aus der Tabelle mit Metadaten der aktuellen Datenbank aus und erkennt somit, dass Version 1 installiert ist
  2. Es schaut in das Verzeichnis mit den Update-Scripts und ermittelt welche Updates installiert werden können. Nachdem dort die Datei Update-2.sql liegt, ist klar, dass dieses Script noch ausgeführt werden muss
  3. Das Script Update-2.sql wird ausgeführt und somit die DB auf den aktuellen Stand gebracht

Was jetzt noch fehlt ist, die Möglichkeit das durchgeführte Update auch zu überprüfen. Nachdem das Datenbankschema in Form einer XML-Datei (Dezign for Databases) vorliegt könnte ich mir vorstellen, dass man sich entsprechende Integrationstests aus diesem Modell generieren kann.

Sind nun alle Anforderungen erfüllt?

okDer Build Server soll Datenbank-Updates automatisch ausführen/testen können

Der Benutzer erzeugt die Update Scripts, welche vom Build Server ausgeführt werden. Automatische Tests sind möglich, wenn man z.B. Test-Code aus der Dezign XML-Datei generiert.

okDie Daten sollen bei einem Datenbank Update nicht verloren gehen, sondern ggf. migriert werden

Der Entwickler hat sicherzustellen, dass die Migrationen alle durchgeführt werden. In einem weiteren Schritt könnten Integrationstests geschrieben werden, welche die erfolgreiche Migration überprüfen.

okDer Gesamtprozess soll unabhängig vom verwendeten DBMS sein

Dezign for Databases unterstützt alle gängigen Datenbanken. Das Update-Tool ist eine Eigenentwicklung und kann somit für weitere DBMS angepasst werden

okDer Gesamtprozess soll möglichst bei Projektstart schon eingehalten/durchgeführt werden können

Aufgrund der Tatsache, dass hier ein generischer Ansatz gewählt wurde kann diese Vorgehensweise für alle zukünftigen Projekte unter Zuhilfenahme derselben Tools sofort bei Projektstart umgesetzt werden.

Der Punkt bzgl. Export und Import wird hier bei natürlich nicht berücksichtigt. Das bedeutet, dass die Migration von alten Exports für die Verwendung in neueren Softwareversionen noch einmal separat implementiert werden müssen.

Methode 2: Export der Daten, neues Schema einspielen, Import der Daten

Nachdem erkannt wurde, das hier das DRY (Don’t repeat yourself) Prinzip nicht eingehalten wird, kam der Vorschlag, dass man den Export und Import dann doch auch für die DB-Migrationen über die Versionen hinweg verwenden könnte.

  1. Aktuelle Daten exportieren
  2. Datenbank komplett löschen
  3. Neues DB-Schema einspielen
  4. Daten wieder importieren (und dadurch automatisch migrieren)

Das hört sich erstmal sehr gut an, weil die Migration von Daten nur an einer Stelle durchgeführt und implementiert werden muss, erfüllt aber nicht alle Anforderungen:

Der Gesamtprozess soll möglichst bei Projektstart schon eingehalten/durchgeführt werden können

 

Es muss bereits der gesamte Export-Import-Mechanismus implementiert sein, um den Prozess so umzusetzen zu können. Dadurch kann der Prozess bei Projektstart noch nicht eingehalten werden.

Weitere Nachteile:

  1. Gerade der Import kann nicht generisch implementiert werden und muss somit mit jeder kleinen DB-Änderung angepasst werden
  2. Der Import ist schwierig und langwierig zu testen. Ein häufiges Anpassen des Imports führt zu häufigen und unnötigen Test-Schleifen

=>Der Export-Import sollte jeweils kurz vor der Veröffentlichung eines Produktiv-Releases angepasst werden. Dadurch können unnötige Schleifen vermieden werden und Tests ausführlicher durchgeführt werden (z.B. Exports aller vorhergehender Versionen im Import testen). Klar, man könnte natürlich auch „nur“ die Tests an das Ende eines Produktiv-Inkrements stellen, aber m.E. würde trotzdem die Qualität des Imports darunter leiden, weil sich niemand an geeigneter Stelle nur einmal Gedanken macht, was bei einem Import der älteren Version nun alles migriert werden muss.

Fazit

Obwohl das DRY-Prinzip bei Methode 1 nicht eingehalten wird erscheint diese doch als die Bessere. Vor allem der Nachteil, dass bei Methode 2 bereits jede Menge implementiert sein muss, damit sie angewendet werden kann wird zum Killerkriterium. Wir werden also vorerst darauf setzen und dies in einem nächsten Projekt genau so umsetzen.

 

 

 

KISSing Markdown

von Patrick Bédat, 28. Juli 2013

Sharing is Caring

Vor kurzen erstellte ich ein Stellenangebot in Word und wollte mir die Meinung meiner Kollegen dazu einholen. Aber ein Word-Dokument per Anhang teilen? Nein, da könnte ich ja genau so gut ein FAX schreiben. Also rein damit in unser Corporate Google Drive, für die Kollegen freigeben und auf Feedback warten.

Im nächsten Schritt sollte die Anzeige natürlich auch auf unsere neue Homepage. Gerade als ich das erste <h1> wieder geschlossen habe hat sich die DRY-Düse in meinem Hinterkopf zu Wort gemeldet: „Don‘t repeat yourself!“ zischte es leise, aber in einem scharfen Tonfall.

Keep it simple, stupid

Wir nutzen glücklicherweise kein überproportioniertes CMS, das Google Docs Inhalte auf automagische Weise in unsere Seite integriert, sondern ein leichtgewichtiges selbstgebautes Framework, zum Hosten von statischem Inhalt. Ich suchte also ein Format, das ich meine Kollegen reviewen lassen kann ohne sie mit spitzen Klammern zu verletzen und das sich trotzdem leicht als Content in unsere Webseite integrieren lässt.

Zugegeben, wirklich suchen musste ich nicht. Markdown ist mittlerweile zu meinem Standard für jegliche Art von Textdatei geworden und ich war auch wenig überrascht, als ich feststellte, dass ich schon vor langer Zeit eine Markdown-Erweiterung in mein Visual Studio integrierte.

Visual Studio bietet zahlreiche Erweiterungen für Markdown an. Aber aufgrund der sehr gut lesbaren Syntax, sind diese eigentlich überflüssig.

Visual Studio bietet zahlreiche Erweiterungen für Markdown an. Aber aufgrund der sehr gut lesbaren Syntax, sind diese eigentlich überflüssig.

Ubiquitous awesomeness

Markdown, ein fast schon allgegenwärtiger Standard im Web (StackOverflow, Git, BitBucket, etc.), rendert wunderbar lesbaren Markup-Code in HTML. Ich erstelle also mein Stellenangebot nochmal im Markdown-Format und siehe da:  Aus unserem Mini-Framework wird so eine Art Content Management System!

Die Markdown-Datei wird von einer HtmlHelper Extension Method gerendert.

Und heraus kommt ein tolles neues Stellenangebot!

Einziger Wermutstropfen für mich als Confluence User: Atlassian hat sich irgendwann entschieden den Markdown-Support für Confluence zu entfernen. Argument: Für Leute mit nur wenig technischen Bezug sei Markdown wohl zu avantgardistisch 😉