Mittwoch, 14. September 2016

Robust Code: Update von Daten mittels Switch

Stell dir vor du downloadest regelmäßig eine Datei, die du danach weiter verarbeitest. Hier zur Illustration als Bash:

curl -sS "http://eber-p.com/report.csv" | wc -l

Wenn jetzt der Download aus irgend einem Grund fehlschlägt, dann bricht die Datenverarbeitung ab. Dein Service liefert keine Ergebnis mehr. Hier pflanzt sich ein Fehler durch mehrere Systeme fort. Das kann gewollt sein, meistens möchte man aber eine robuste Lösung die nicht bei jedem Downloadfehler zusammenbricht. Dies kann man erreichen, in dem man die alte Datei nicht überschreibt, sondern als Fall Back behält und sie ggf. erst nach einem erfolgreichen Download überschreibt.

wget "http://eber-p.com/report.csv" 
r=`ls -t report.csv* | head -n 1`
cat $r | wc -l   


Wichtig ist nur, dass man die Benutzung des Fall Backs dokumentiert, im Log File und oder in der Antwort des Services. Letztere wird hier nicht gemacht.

Kurz zusammengefasst die robuste Softwarelösung:

  1. Lose Kopplung von Programmteilen die unterschiedliche Funktionen hat, hier Datenbeschaffung und Logik (hier zählen der Zeilen des Reports). 
  2. Puffern von alten Daten und Nutzung von diesen Daten als Fallback.


Hier das ganze Beispiel-Skript:
#! /bin/sh

echo "Test with right URL"
u="http://ebert-p.com/report.csv"

echo "Non robust code"
curl -sS  $u | wc -l

echo "Robust code"
wget -q -a log.log  $u
r=`ls -t report.csv* | head -n 1`
cat $r | wc -l         


echo "Test with wrong URL"
u="http://ebert-p.com/report_wrong.csv"

echo "Non robust code"
curl -sS  $u | wc -l

echo "Robust code"
wget -q -a log.log  $u
r=`ls -t report.csv* | head -n 1`
cat $r | wc -l   

Und die Konsolen Ausgabe:
Test with right URL
Non robust code
    1518
Robust code
    1518
Test with wrong URL
Non robust code
      24
Robust code
    1518

Nicht-Funktionale Anforderung: Software Robustness

Robustheit ist die Toleranz gegenüber Fehlern. Robustheit gehört damit zu den nicht-funktionalen Anforderungen. Die Toleranz gegenüber Fehlern kann auf unterschiedliche Weise realisiert werden. Systeme gelten als robust, wenn sie folgende Eigenschaften hat:

  1. Ein Fehler führt nicht zum Ausfall des gesamten Systems.
  2. Das System kann Fehler selbst beheben oder umgehen.
  3. Die Auswirkung eines Fehlers bleiben lokal begrenzt, sowohl aus zeitlicher als auch aus Systemsicht.

Robustheit zahlt direkt auf die Verfügbarkeit von Systemen ein, sowohl was die Häufigkeit von Störungen als auch auf den zeitlichen Umfang der Störung angeht. Oder anders formuliert, robuste Softwaresysteme haben eine höhere Verfügbarkeit als weniger robuste Softwaresysteme.

Robustheit kann durch verschieden Massnahmen erreicht werden:

  1. Redundanz
  2. Robuste Software Architektur
  3. Exception Handling
  4. Fall Backs
  5. Funktionsreduktion

Alles was man nicht testet funktioniert auch nicht, so auch Software Robustheit. Deswegen muss Robustheit auch durch Robustheitstests gesichert werden.

Dienstag, 13. September 2016

Sicherheitsproblem API Token

API Token sind eine einfache Möglichkeit um den Zugriff auf z.B. Rest API zu steuern. Ein API Token ist in der Regel ein längerer String mit zufälligem Inhalt, der dem Programmierer den Zugriff auf das API erlaubt. Der Benutzer bzw. Programmierer wird identifiziert sich mittels des API Tokens. Wie Kristopher Sandoval in seinem Blog Artikel ausführt, sollten man kritisch auf die scheinbare Sicherheit der API Token schauen. Zum Umgang mit API Token hier ein paar Tipps:

  1. Einen API Token sollte man wie privaten SSH Key behandeln. 
  2. Man sollten ihn auf keinen Fall innerhalb des Projektes, egal ob in einer plain Textdatei oder im Code haben. 
  3. Im einfachsten Fall sollte man den API Token im hoffentlich gesicherten User Verzeichnis ablegen, auf dem hoffentlich verschlüsseltem Disk Volumen.
  4. Bei Rest APIs sollte der API Token nur per sicherem HTTPS benutzt werden.
  5. Der API Token sollte nie in öffentliche Code Repos wie Github gepostet werden. Das Entfernen von solchen Git Pushes ist kein Spass. Hier kann ein Git Hook (pre-commit) hilfreich sein, der den Code nach verdächtigen Strings oder Dateien durchsucht.
  6. Auch sollten sie nicht in Wikis abgelegt werden.

Links:

Dienstag, 30. August 2016

Docker at Digital Ocean

Start an Centos Droplet at Digital Ocean with Docker Machine:

$ docker-machine create --driver digitalocean --digitalocean-region "fra1" --digitalocean-size "1gb" --digitalocean-image "centos-7-2-x64" --digitalocean-access-token $DOTOKEN mer

Remarks:

  1. Update your docker installation, because a bug prevent using Centos with Docker on Cloud provider like Digital Ocean.
  2. Digital Ocean regions must be lower case.
  3. You need an API Token at Digital Ocean. 
  4. Look at image syntax "Centos 7.2 x64" -> "centos-7-2-x64"

Sonntag, 31. Juli 2016

Tinkerforge IoT First Steps Java Project launched on Github

I launched the first steps Java project for learning Tinkerfor ge and IoT (Github).

It uses following hardware as my simple and low cost starter kit:

  • Master Brick
  • Segment Display 4x7 Bricklet
  • Teperature Bricklet
  • Ambient Light Bricklet
  • Accelerometer Prickelt


The newbie can start with some experiments or challenges:

  • Hello World
  • Simple Themometer
  • Thermomenter and Clock
  • Small weather station with temeperatur, time and illumination
  • Resource saving programming with Call Backs/Listeners
  • Ambient Light sensor as contactless display light switch
  • Accelerometer as contactless switch
Code examples helps to realize the challenges.

Tinkerforge Weather Station published on Github

Tinkerforge is electronics framework for software developers. It's a good starting point for your own Internet of Things (IoT).  So I decide to bye me a starter kit. I choose the weather station kit.

Now, after some time I publish my Tinkerforge Weather Station Java Project on Github (Link). Its simple and robust. It uses callbacks to recognize on sensor changes. and runs over days without problems. It measures humidity, air pressure, ambient light and temperature. The temperature is measured indirectly via chip temperature of the humidity bricklet. Special features are, switching the display light depending on ambient light, show alternating date and time and show warnings because of to low or high humidity. If you put your hand over the ambient light sensor, the sensor works as contactless light switch.


If you are looking for more information on Tinkerforge, you can read the book (Kindle, german only) from Sven Ruppert: Einführung in die Heimautomatisierung: IoT mit Tinkerforge.


Mittwoch, 13. Juli 2016

Run All Test on File Change

Eines der besten Instrumente um Code zu verbessern sind Test, speziell Unit Tests. Unit Test sind für alle erdenklichen Programmiersprachen verfügbar und wenn nicht, dann schreibt man sich den Test selbst, ohne Frame Work. Mit Hilfe der Unit Test können Fehler einfach aufgedeckt werden dazu muss man nicht nur die Test haben, sondern sie auch permanent ausführen. Dieses permanente Ausführen ist die Aufgabe des Continouse Integration Servers, z.B. Jenkins. Alternativ gibt es auch die Unit Integration in die IDE. Wem selbst der Jenkins oder die IDE zu langsam ist, schnelle Roundtripzeiten bedeuten effizientes Entwickeln, der kann sich mit Hilfe eines einfachen Scripts seine Test ausführen, wenn sich etwas am Quellcode der Software oder der Test geändert hat (File save).

Hier ein Beispiel für den Mac, dass Unit Test für R ausführt und den Entwickler per Notification auf Fehler bei der Testdurchführung hinweist. Zuerst muss per Homebrew fswatch installiert werden. Dann muss dieses Script ins Root Verzeichnis deines Projektes abgelegt werden. Dann muss es starten. Es läuft ohne Unterbrechung solange, bis man via CRTL + C abbricht. Alternativ kann man das Script für andere Umgebungen anpassen.


#!/usr/bin/env bash

runX=true

finish (){
    runX=false
}
trap finish SIGINT


runTests(){
    for SCRIPT in src/test/*
    do
        if [ -f $SCRIPT -a -x $SCRIPT ]
        then
            $SCRIPT
            if [[ $? -ne 0 ]] 
            then
                FAILEDTESTS=${FAILEDTESTS}"\n"$SCRIPT
            fi
        fi                                                      
    done
    if [ ${#FAILEDTESTS} -ge 1 ]
    then
        osascript -e 'display notification  "'"$FAILEDTESTS"'" with title "R Test failed"'
        FAILEDTESTS=""
    fi
}

while $runX; do
    fswatch src/main/*.R src/test/*.R | runTests 
done