Robert Basic's blog

Hiking the Uvac special nature reserve

by Robert Basic on July 27, 2016.

In 2014 my wife Senka and I went on a camping vacation in Greece, on the Lefkas island. It was the first time camping for her, while I did some camping the year before. We quickly realised that we both enjoy camping very much and agreed to go on as many camping trips as possible.

The following year we went on a 12 day long camping and hiking vacation in Italy. The weather had different plans for us, so we only managed to do two hikes there — one in Seiser Alm and one in Cinque Terre.

This year for our honeymoon we went to Norway where we managed to do an amazing 4 hikes for the 8 days we were there. The view from Preikestolen is mind-boggling.

This past weekend the two of us went on a camping and hiking weekend getaway at the Uvac special nature reserve. Apparently this was our 10th hike so I thought it would only be fitting to remember it with a blog post. I might write about our other experiences in the future.

We chose Uvac as we agreed to see more of our country, the entire region is just gorgeous, the nature is barely touched by humans and the reserve is the home to the endangered Griffon Vulture.

Choosing the trail

There are only a handful of resources online about the camping and hiking possibilities around here (this is mostly true for all of Serbia, not just the Uvac region). We found a couple of hiking trails that we liked and a detailed inspection of one of the trails on Open Street Map and Google Maps revealed there’s a camping site by the trail, on the banks of the Sjenica lake. I got in contact with the reserve’s custodians who got me in touch with the ranger who is responsible for that area. They were all very helpful over the phone and answered all my questions in a couple of minutes.

The trail is the Uvac meanders and Molitva (Prayer) peak trail.

Driving from Novi Sad

The drive from Novi Sad to the camp took us some 7 hours, with one stop. The route was Novi Sad — Šabac — Valjevo — Kosjerić — Požega — Užice — Zlatibor — Nova Varoš — Sjenica — camp. We left the city in the rush hour and the traffic was pretty heavy until Šabac which is some 70kms away. The road from there was surprisingly good, with only maybe two patches of the asphalt being really bad for a total of cca. 30km. A slow, but not a tiring drive all things considered. The nature along the way makes up for it.

Arriving at the camp

The path to the camp is not clearly marked on the road. There is a junction at which we had to go off of the main road and there’s maybe a kilometer or so of gravel road to get to the camp. I was hoping to arrive there while there was still some daylight left, but we ended up arriving just as the Sun set. We were welcomed by the campers and I’m not even sure there was an “official” person from the camp or from the reserve there. They helped us pick a spot for our tent and invited us for a barbecue dinner after we were all set up. A bottle of rakija was also going around.

The camp is not like the camps we stayed at before. It has no showers or toilette facilities. There’s one fountain with spring water and one of those wooden field toilets. There are no visible tent spots, it’s more of a who settles where kind of a camp. A bit chaotic, but it does have it’s charm. In the mornings the camp site and the surounding area was covered in a mist, really pretty sight while the Sun comes up over the hills.

All in all for the two nights we were there, it was good enough. We only paid the 100 dinars (less than 1 euro) entry fee to the park and that’s it. The actual camping was free, so we can’t complain about a single thing.

The hike

Saturday morning we got up a bit after 7am, had coffee and tea, some breakfast and prepared for the hike.

Senka made sandwiches and I packed the water, compass, maps and the likes for our hike. As usual we took way too much food, but the 9 liter of water was just enough. We drank more than 7 liters for the 7 hours we were out on the trail. The Sun was relentless that day.

The trail is nicely marked, it is both clearly visible and has the trail markings at regular distances. It was a bit overgown here and there, but nothing serious. It passes through, I think, two wooded parts at the beginning of the trail and after that it’s pretty much Sun all the way to the top and back. Pack sunscreen if you go in clear weather.

What we liked a lot was the fact that it wasn’t crowded. Every 30 minutes or so we would come across a group of hikers, have a short chat with them and then move along. We could enjoy the nature and the views on our own, but we still didn’t feel completely alone. Just the perfect sweet spot of “traffic” on the trail.

Apart from the hot Sun, there weren’t really any other problems with the hike. One mountain guide we came across told us that doing the hike in short pants wasn’t really smart because apparently there are snakes on the trail. Stupid from us not looking that up beforehand and preparing accordingly.

At the top of the trail there is a viewpoint from which we could appreciate the view and look at the huge scavenger birds flying around looking for food.

On our way back to the camp, we went down to the river and had a nice swim. There is one short path down from the trail to the river bank, but it is seriously overgrown and barely visible so be extra careful if you decide to do the same.

Other activities in the area

Apart from hiking, it also possible to go on a boat cruise down the river and back, with optional stops at a couple of caves to go spelunking as well as fishing. For these you’ll have to make prior arrangements with one of the guides or park rangers.

You can also try and buy some Sjenica cheese, which is sold by a household near at the top of the trail. People say it’s really delicious, but we haven’t tried it ourselves.

Happy hiking!

Tags: Griffon Vulture, Uvac, camp, camping, hike, hiking, nature, reserve.
Categories: Blablabla, Free Time.

Missing colors for PHPUnit

by Robert Basic on July 20, 2016.

I ran accross a minor issue today that I never experienced before. The colors for the PHPUnit’s output were missing. I had the colors=true directive set in the phpunit.xml configuration file, but the output was just black and white.

Turns out I was missing the posix extension, which is provided by the php-process package on Fedora. After installing it:

$ sudo dnf install php-process

all was good again in the world of unit testing.

Oh well.

Happy hackin’!

Tags: php, phpunit.
Categories: Development, Programming, Software.

Using Tactician in a Zend Expressive application

by Robert Basic on July 13, 2016.

I spent some time connecting the dots last week, so I decided to put together an example on how to get started with using Tactician in a Zend Expressive application. The example itself is not really useful, but it does show how to setup the dependencies and get started with these two libraries.

Zend Expressive is a PSR7 compatible microframework that provides interfaces for routing, DI containers, templating and error handling. It provides a couple out of the box, so you can either use those, or write your own implementations.

Tactician is a command bus library whose goal is to make using the command pattern easy to use in your applications. It allows to have an object that represents a command, pass it on to the command bus which will figure out which command handler should take care of that command.

Let’s dive in

To get up and running quickly with Zend Expressive we can create a skeleton application. It does some basic wiring for us, like setting up the routing and the DI container.

It also comes with a dummy ping action, at /api/ping, which just gives us the current unix timestamp. This example is going to expand on that and create a Ping command that will be handled by a Ping command handler. The command handler will get some additional dependencies from the container, just to make the example a bit more interesting.

Creating the skeleton application is really easy with Composer:

$ cd /var/www
$ composer create-project zendframework/zend-expressive-skeleton tactician-example

Bring in the Tactician and the tactician-container plugin as project dependencies. The tactician-container plugin allows us to lazy load command handlers from a container-interop compatible container:

$ composer require league/tactician
$ composer require league/tactician-container

Now that we have all our libraries in, let’s change how the container creates the Ping action. Before it was being just invoked by the container, but now we want to create it through a factory:

config/autoload/routes.global.php

diff --git a/config/autoload/routes.global.php b/config/autoload/routes.global.php
index 856f5ab..8335450 100644
--- a/config/autoload/routes.global.php
+++ b/config/autoload/routes.global.php
@@ -4,10 +4,10 @@ return [
     'dependencies' => [
         'invokables' => [
             Zend\Expressive\Router\RouterInterface::class => Zend\Expressive\Router\FastRouteRouter::class,
-            App\Action\PingAction::class => App\Action\PingAction::class,
         ],
         'factories' => [
             App\Action\HomePageAction::class => App\Action\HomePageFactory::class,
+            App\Action\PingAction::class => App\Action\PingFactory::class
         ],
     ],

This will allow us to pass in dependencies to the PingAction class.

The Ping action’s factory is simple:

src/App/Action/PingFactory.php

<?php

namespace App\Action;

use Interop\Container\ContainerInterface;

class PingFactory
{
    public function __invoke(ContainerInterface $container)
    {
        $commandBus = $container->get('CommandBus');

        return new PingAction($commandBus);
    }
}

We are telling the container to get the service called CommandBus and pass it as an argument to the Ping action’s constructor.

Wiring in Tactician

We haven’t yet defined the CommandBus service, so let’s do that next by telling the service manager to create the CommandBus using the App\CommandBusFactory factory:

config/autoload/dependencies.global.php

diff --git a/config/autoload/dependencies.global.php b/config/autoload/dependencies.global.php
index b2b08f5..460c045 100644
--- a/config/autoload/dependencies.global.php
+++ b/config/autoload/dependencies.global.php
@@ -19,6 +19,7 @@ return [
         'factories' => [
             Application::class => ApplicationFactory::class,
             Helper\UrlHelper::class => Helper\UrlHelperFactory::class,
+            'CommandBus' => App\CommandBusFactory::class
         ],
     ],
 ];

This factory sets up the Tactician’s command bus and is the main point of this example:

src/App/CommandBusFactory.php

<?php

namespace App;

use League\Tactician\CommandBus;
use League\Tactician\Handler\CommandHandlerMiddleware;
use League\Tactician\Container\ContainerLocator;
use League\Tactician\Handler\CommandNameExtractor\ClassNameExtractor;
use League\Tactician\Handler\MethodNameInflector\InvokeInflector;
use Interop\Container\ContainerInterface;

class CommandBusFactory
{
    public function __invoke(ContainerInterface $container)
    {
        $inflector = new InvokeInflector();

        $commandsMapping = [];
        $locator = new ContainerLocator($container, $commandsMapping);

        $nameExtractor = new ClassNameExtractor();

        $commandHandlerMiddleware = new CommandHandlerMiddleware(
            $nameExtractor,
            $locator,
            $inflector
        );

        $commandBus = new CommandBus([
            $commandHandlerMiddleware
        ]);

        return $commandBus;
    }
}

Tactician uses a command handler middleware to handle commands. That middleware in turn uses a name extractor to get the command name out of a command, a locator to find the actual command handler and an inflector to figure out the method to call on the command handler to handle the command. Tactician’s middleware system is nicely described in the documentation.

The ClassNameExtractor will extract the command name from the class name.

The ContainerLocator will use our container-interop compatible container to find the command handler, which in this example is Zend ServiceManager.

The InvokeInflector dictates that the command handler needs to have an __invoke method which will get our Ping command as an argument and then it’s up to the Ping command handler to handle the command.

The $commandsMapping array that we are passing to the locator is going to be a map of commands and their handlers. We’ll populate that later on.

In the next step, let’s tell the PingAction’s constructor to accept the command bus:

src/App/Action/PingAction.php

diff --git a/src/App/Action/PingAction.php b/src/App/Action/PingAction.php
index ea2ae22..612fb32 100644
--- a/src/App/Action/PingAction.php
+++ b/src/App/Action/PingAction.php
@@ -5,9 +5,15 @@ namespace App\Action;
 use Zend\Diactoros\Response\JsonResponse;
 use Psr\Http\Message\ResponseInterface;
 use Psr\Http\Message\ServerRequestInterface;
+use League\Tactician\CommandBus;

 class PingAction
 {
+    public function __construct(CommandBus $commandBus)
+    {
+        $this->commandBus = $commandBus;
+    }
+
     public function __invoke(ServerRequestInterface $request, ResponseInterface $response, callable $next = null)
     {
         return new JsonResponse(['ack' => time()]);

Cool, at this point we have everything set up to start sending and handling commands.

Commands and their handlers

The command we are going to create is a simple one:

src/App/Command/Ping.php

<?php

namespace App\Command;

class Ping
{
    private $commandTime;

    public function __construct()
    {
        $this->commandTime = time();
    }

    public function getCommandTime()
    {
        return $this->commandTime;
    }
}

It just sets the command time to the current unix timestamp.

Updating the PingAction to include the creation of our Ping command and passing it on to the command bus to be handled:

src/App/Action/PingAction.php

diff --git a/src/App/Action/PingAction.php b/src/App/Action/PingAction.php
index 612fb32..6cb9334 100644
--- a/src/App/Action/PingAction.php
+++ b/src/App/Action/PingAction.php
@@ -6,6 +6,7 @@ use Zend\Diactoros\Response\JsonResponse;
 use Psr\Http\Message\ResponseInterface;
 use Psr\Http\Message\ServerRequestInterface;
 use League\Tactician\CommandBus;
+use App\Command\Ping as PingCommand;

 class PingAction
 {
@@ -16,6 +17,11 @@ class PingAction

     public function __invoke(ServerRequestInterface $request, ResponseInterface $response, callable $next = null)
     {
-        return new JsonResponse(['ack' => time()]);
+        $pingCommand = new PingCommand();
+        $time = $pingCommand->getCommandTime();
+
+        $this->commandBus->handle($pingCommand);
+
+        return new JsonResponse(['ack' => $time]);
     }
 }

Now is the time to let Tactician know about our command and command handler mapping, so it knows which handler handles which command:

src/App/CommandBusFactory.php

diff --git a/src/App/CommandBusFactory.php b/src/App/CommandBusFactory.php
index ba587f6..b79fbb1 100644
--- a/src/App/CommandBusFactory.php
+++ b/src/App/CommandBusFactory.php
@@ -9,13 +9,18 @@ use League\Tactician\Handler\CommandNameExtractor\ClassNameExtractor;
 use League\Tactician\Handler\MethodNameInflector\InvokeInflector;
 use Interop\Container\ContainerInterface;

+use App\Command\Ping as PingCommand;
+use App\CommandHandler\Ping as PingCommandHandler;
+
 class CommandBusFactory
 {
     public function __invoke(ContainerInterface $container)
     {
         $inflector = new InvokeInflector();

-        $commandsMapping = [];
+        $commandsMapping = [
+            PingCommand::class => PingCommandHandler::class
+        ];
         $locator = new ContainerLocator($container, $commandsMapping);

         $nameExtractor = new ClassNameExtractor();

We’re almost there. I promise.

The command handler is going to be created through a factory, so we can inject dependencies into it:

src/App/CommandHandler/PingFactory.php

<?php

namespace App\CommandHandler;

use Interop\Container\ContainerInterface;

class PingFactory
{
    public function __invoke(ContainerInterface $container)
    {
        $logPath = '/tmp/ping-command.log';

        return new Ping($logPath);
    }
}

It doesn’t do much, it just passes a path to a log file. Of course, in real code, you’d probably pass in some dependency gotten from the container.

The command handler won’t do much either, it’s just going to log the the ping’s command time in the log file we passed in from the command handler factory:

src/App/CommandHandler/Ping.php

<?php

namespace App\CommandHandler;

use App\Command\Ping as PingCommand;

class Ping
{
    private $logPath;

    public function __construct($logPath)
    {
        $this->logPath = $logPath;
    }

    public function __invoke(PingCommand $pingCommand)
    {
        $commandTime = $pingCommand->getCommandTime();

        file_put_contents($this->logPath, $commandTime . PHP_EOL, FILE_APPEND);
    }
}

And finally let the service manager know how to create the Ping command handler:

config/autoload/dependencies.global.php

diff --git a/config/autoload/dependencies.global.php b/config/autoload/dependencies.global.php
index 460c045..2c8e3ee 100644
--- a/config/autoload/dependencies.global.php
+++ b/config/autoload/dependencies.global.php
@@ -19,7 +19,8 @@ return [
         'factories' => [
             Application::class => ApplicationFactory::class,
             Helper\UrlHelper::class => Helper\UrlHelperFactory::class,
-            'CommandBus' => App\CommandBusFactory::class
+            'CommandBus' => App\CommandBusFactory::class,
+            App\CommandHandler\Ping::class => App\CommandHandler\PingFactory::class
         ],
     ],
 ];

Navigating to /api/ping should display the {“ack”:1468171544} response, and the log file at /tmp/ping-command.log should have the same timestamp logged.

That was a lot of code

I know, looks like an awful lot of code just to log a timestamp in a file somewhere. But the point is that even for more complicated commands and handlers the basic wiring stays the same — create the CommandBus factory, set up mapping of commands and handlers and the rest is pretty much the business logic of the application.

Happy hackin’!

P.S.: I’m trying out this new way of providing code samples by using diffs, so it’s easier to follow what changed where. Let me know how it looks, thanks!

Tags: command bus, container, php, tactician, zend expressive.
Categories: Development, Programming.

Setting up SSL certificates with Let's Encrypt

by Robert Basic on July 06, 2016.

SSL Report Summary

This past week I finally got around to setting up SSL certificates using Let’s Encrypt. Let’s Encrypt is an open certificate authority that provides free SSL/TLS certificates. It’s goal is to make creating, renewing and using SSL certs painless.

And it most certainly is. I was expecting a lot more hassle to set up all this, but it was really easy to do.

Install certbot

Certbot is a Let’s Encrypt client that helps setting up a certificate by obtaining and installing it on your servers. There are many more clients out there, but certbot is the recommended one to use.

I simply installed certbot using dnf:

sudo dnf install certbot

but if your OS has no package for it yet, there’s always the manual way.

Creating a certificate

Certbot has a number of plugins that can be used to create and install a certificate on a server. I chose the webroot plugin which only gets the certificate for me and leaves the webserver configuration up to me.

sudo certbot --text --renew-by-default --agree-tos --webroot \
--email youremail@domain.tld \
--domains domain.tld,www.domain.tld \
--webroot-path /path/to/site/public \
certonly

This will create the certificate and it’s private key in the /etc/letsencrypt/live/domain.tld/ directory.

Configuring nginx

The next step is to configure nginx by enabling SSL, providing the paths to the certificate and the private key, and which protocols and ciphers to use. I added these to the server block:

listen 443 ssl;

ssl on;
ssl_certificate /etc/letsencrypt/live/domain.tld/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/domain.tld/privkey.pem;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_ciphers ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:ECDH+3DES:DH+3DES:RSA+AESGCM:RSA+AES:RSA+3DES:!aNULL:!MD5:!DSS;

After restarting nginx, you should be able to load up your site through https. Just remember to allow traffic on the 443 port:

sudo firewall-cmd -add-service=https --permanent
sudo firewall-cmd reload

Additional configuration

To further harden the Diffie-Helman key exchange, create new parameters for it using openssl:

sudo mkdir /etc/nginx/ssl
cd /etc/nginx/ssl
sudo openssl dhparam -out dhparams.pem 2048

I told nginx to use it by adding it to the same server block where I set up the SSL configuration:

ssl_dhparam /etc/nginx/ssl/dhparams.pem;

I also did some SSL optimizations and enabled Strict Transport Security:

ssl_session_timeout 10m;
ssl_session_cache shared:SSL:10m;
ssl_buffer_size 8k;
add_header Strict-Transport-Security max-age=31536000;

This blog post explains HTTP Strict Transport Security nicely.

All this and my website gets an A+ rating on the Qualys SSL Server Test.

Enable OCSP stapling

Thanks to Goran Jurić for pointing out to enable OCSP stapling. I did so by adding this to the nginx server config:

ssl_stapling on;
ssl_stapling_verify on;

According to the nginx documentation the ssl_trusted_certificate directive is needed only when the ssl_certificate file does not contain intermediate certificates, but the fullchain.pem created by Let’s Encrypt does contain them, so I’m skipping that.

To test whether OCSP stapling is enabled, reload nginx, and from a local terminal run the following:

openssl s_client -connect domain.tld:443 -status

The output should have something like:

OCSP response:
======================================
OCSP Response Data:
    OCSP Response Status: successful (0x0)
    Response Type: Basic OCSP Response
    Version: 1 (0x0)
    Responder Id: C = US, O = Let's Encrypt, CN = Let's Encrypt Authority X3
Tags: certbot, certificate, let's encrypt, nginx, ssl, tls.
Categories: Development, Software.

Installing Python2 with Ansible

by Robert Basic on June 29, 2016.

Ansible uses Python2 to run the provisioning commands on the host machines. At this time it does not support Python3, which is the default python version in Fedora releases for quite some time now.

So to be able to manage Fedora machines with Ansible, I need to install Python2, but how to install it when all the Ansible modules depend on Python2 being installed? Turns out it’s quite simple, by turning of the gathering of facts in Ansible and using the raw module to install the required packages:

- hosts: all
  gather_facts: no
  become: yes
  tasks:
    - name: Install python2 and python2-dnf
      raw: dnf -y install python2 python2-dnf
    - name: Gather facts
      setup:

Just remember this needs to be the very first thing that happens on all your Fedora hosts. After python2 is installed, gather the facts for all the hosts by running the setup module.

Happy hackin’!

Tags: ansible, fedora, provisioning, python, vagrant.
Categories: Development, Software.