June 10, 2015 1 minutes and 6 seconds read

HTTPServletRequestWrapper for ServletInputStream 3.1

A HttpServletRequestWrapper may be handy if you want to be able to read the HTTP Body multi times after you consume it in a filter. The ServletInputStream 3.1 changed a bit and the following methods have to be implemented.

  • isFinished
  • isReady
  • setReadListener
import com.google.common.primitives.Bytes;
import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;

public class AuthenticationRequestWrapper extends HttpServletRequestWrapper {

    // tag::variables[]
    private byte[] requestBody = new byte[0];
    private boolean bufferFilled = false;
    // end::variables[]

    /**
     - Constructs a request object wrapping the given request.
     *
     - @param request The request to wrap
     - @throws IllegalArgumentException if the request is null
     */
    public AuthenticationRequestWrapper(HttpServletRequest request) {
        super(request);
    }


    // tag::getRequestBody[]
    public byte[] getRequestBody() throws IOException {
        if (bufferFilled) {
            return Arrays.copyOf(requestBody, requestBody.length);
        }

        InputStream inputStream = super.getInputStream();

        byte[] buffer = new byte[102400]; // 100kb buffer

        int bytesRead;
        while ((bytesRead = inputStream.read(buffer)) != -1) {
            requestBody = Bytes.concat(this.requestBody, Arrays.copyOfRange(buffer, 0, bytesRead)); // <1>
        }

        bufferFilled = true;

        return requestBody;
    }
    // end::getRequestBody[]

    // tag::getInputStream[]
    @Override
    public ServletInputStream getInputStream() throws IOException {
        return new CustomServletInputStream(getRequestBody()); // <1>
    }
    // end::getInputStream[]

    private static class CustomServletInputStream extends ServletInputStream {

        private ByteArrayInputStream buffer;

        public CustomServletInputStream(byte[] contents) {
            this.buffer = new ByteArrayInputStream(contents);
        }

        @Override
        public int read() throws IOException {
            return buffer.read();
        }

        @Override
        public boolean isFinished() {
            return buffer.available() == 0;
        }

        @Override
        public boolean isReady() {
            return true;
        }

        @Override
        public void setReadListener(ReadListener listener) {
            throw new RuntimeException("Not implemented");
        }
    }
}

June 5, 2015 3 minutes and 54 seconds read

Installing Docker Registry 2.0.1 using self signed certificates

The new Docker Registry (2.x) has just been released and is rewritten in Go. The default installation now requires SSL security and I was looking for a way to secure the Registry using a NGINX SSL proxy where users need to provide username/password to access the registry. The setup of the NGINX proxy can be done manually but i decided to see if i can reuse the excellent images from Container Solutions to ease the installation.

So the setup will be that we install the Docker Registry and proxy the SSL user access via self signed certificates using an NGINX proxy image provided by Container Solutions. Check here for more information

Installation of the remote docker registry will be done by using on an Amazon EC2 (Linux AMI). Currently the free tier Amazon Linux AMI 2015.03 (HVM), SSD Volume Type - ami-a10897d6. So spin up the Amazon AMI and let’s install Docker.

Note: when you spin up your Amazon AMI make sure to remember the FQDN/DNS name! We need this name to generate the SSL certificates!

Example:
<domain-name> = ec2-52-16-247-220.eu-west-1.compute.amazonaws.com

So spin up your AMI and install Docker!

Installing docker

  • login into your Amazon AMI
  • update the system and install Docker
$ sudo yum update -y
$ sudo wget -qO- https://get.docker.com/ | sh
  • add the ec2-user to the docker group (optional)
$ sudo usermod -aG docker ec2-user
  • start Docker
$ sudo service docker start
  • make sure Docker can run the basic “hello-world”
$ sudo docker run hello-world

Create Docker Registry data and configuration directories

We are going to store the registry image data inside /opt/docker/registry/data and configuration files such as the ssl certificates and user login inside /opt/docker/registry/conf.

  • create data folders for Docker Registry data and configuration
$ sudo mkdir -p /opt/docker/registry/data
$ sudo mkdir -p /opt/docker/registry/conf

Run the Docker Registry

Now we are able to run the Docker Registry, the data for images that will be pushed are going to be stored in /opt/docker/registry/data and the container will be named docker-registry

  • run the registry and name it docker-registry
$ sudo docker run -d -v /opt/docker/registry/data:/tmp/registry-dev \
--name docker-registry registry:2.0.1
  • test if the registry is actually running
$ sudo docker ps

So now we have a running Docker Registry, but still no SSL proxy and no user accounts to get access to the registry.

Generate self signed certificates for our SSL proxy

The result of the certificate generation will be placed in /opt/docker/registry/conf and named docker-registry.crt and docker-registry.key.

Note: The docker-registry.crt file is important, we will need this later on to configure our local Docker client on the machine that is going to access the remote registry. So after generating the docker-registry.crt file, grab this and store it on your local machine in a place where you can find it.

  • generate the certificates
$ sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
-keyout /opt/docker/registry/conf/docker-registry.key \
-out /opt/docker/registry/conf/docker-registry.crt

Accept all defaults and make sure you give the correct FQDN /DNS name = <domain-name>.

Create passwords for access to the Docker Registry

In order to let users login into the registry we need to create users (user1/user2). This will be done by using htpasswd. The user data will be stored in docker-registry.htpasswd file and placed in the /opt/docker/registry/conf directory.

  • install htpasswd
$ sudo yum install httpd-tools -y
  • create the users
$ sudo htpasswd -c /opt/docker/registry/conf/docker-registry.htpasswd user1
$ sudo htpasswd /opt/docker/registry/conf/docker-registry.htpasswd user2

Note: when creating the second user omit the -c otherwise the docker-registry.htpasswd file will be get overwritten!

Run the NGINX Proxy

As mentioned we are going to use the image from Container Solutions to run our NGINX proxy.

  • start the NGINX proxy and name it docker-registry-proxy
$ sudo docker run -d -p 443:443  \
-e REGISTRY_HOST="docker-registry" -e REGISTRY_PORT="5000" -e SERVER_NAME="localhost" \
--link docker-registry:docker-registry \
-v /opt/docker/registry/conf/docker-registry.htpasswd:/etc/nginx/.htpasswd:ro \
-v /opt/docker/registry/conf:/etc/nginx/ssl:ro \
--name docker-registry-proxy containersol/docker-registry-proxy

After this step we have a running Docker Registry which is secured using Self Signed certificates and users are able to login using their username/password.

To test this navigate to your registry by using a browser (Chrome) and access: https://<domain-name>:443/v2/. After accepting the security warning provide a username/password and the output should be {}.

Configure the local Docker client

Now that we have a running secured Docker Registry we can configure the Docker client on our machine that is going to access the remote Registry. For this we need a copy of the earlier docker-registry.crt file.

  • copy the docker-registry.crt file from our server to your local machine. This file is located in /opt/docker/registry/conf. Put the copy in a place where you can find it.

Ubuntu Docker Client

In order to get the local client working, we need to install Docker and register the docker-registry.crt certificate file!

  • install docker
$ sudo wget -qO- https://get.docker.com/ | sh
$ sudo service docker start
  • create a directory holding our extra certificates
$ sudo mkdir /usr/share/ca-certificates/extra
  • copy the docker-registry.crt file to the directory /usr/share/ca-certificates/extra

  • register the certificate

$ sudo dpkg-reconfigure ca-certificates

Now you are almost ready!

  • restart the local Docker client
$ sudo service docker restart
  • login onto your remote registry using
$ docker login <domain-name>:port

Now we have a remote Docker Registry and the Docker Client is able to connect!


July 4, 2014 0 minutes and 20 seconds read

Upgrading from Grails 2.3.8 to 2.4.2

When upgrading to Grails 2.4.2 i ran into an issue where the following error message would pop up.

Error creating bean with name 'grailsApplication' defined in ServletContext resource
[/WEB-INF/applicationContext.xml]: Cannot resolve reference to
bean 'grailsResourceLoader' while setting bean property 'grailsResourceLoader';

To solve this issue you need to delete some lines in the <grails-app>/web-app/WEB-INF/applicationContext.xml file.

Delete the following lines:

<property name="grailsResourceLoader" ref="grailsResourceLoader" />

<bean id="grailsResourceLoader" class="org.codehaus.groovy.grails.commons.GrailsResourceLoaderFactoryBean" />

And you should be up and running quickly.


June 9, 2014 0 minutes and 15 seconds read

Skip a contenttype/section to be renderend

When creating a layout it may occur that you want to skip rendering certain types of content, or render only specific content in a part of your layout.

Example: You want to only render contenttype ‘post’ use the following code in your template:

{{ if eq .Type "post" }}

    {{ .Title }}
    {{ .Content }}

{{ end }}

November 27, 2013 1 minutes and 3 seconds read

Bookreview : Instant Vert.x

For those who have not yet got into contact with Vert.x, the book Instant Vert.x (54 pages in total of which 40 pages are “real” content) is a nice introduction to the underlying concepts.

As the name suggests, you can read the book in “an instant” and takes the reader through all high level concepts. The information in the book mostly stays at the concept level and provides some basic usage examples.

For those who have not yet had the opportunity to learn about Vert.x, I would not immediately recommend this book. The online documentation section on Vertx.io contains the same information. But if you like a book with information nicely put into digestible chapters then this book is a good fit.

Personally i hoped to get some more technical information and how-to information from this book but it is really targeted towards people that are just starting or have a beginning interest in Vert.x.

Overall, I really liked the compactness and pace of the book. It is an easy read and you quickly gain knowledge on the high level concepts of Vert.x. While noted earlier you can get the information also on Vertx.io website or other places, it’s is nice to have all information aggregated in one place. This book is a good start in your journey to learn about Vert.x.


May 28, 2013 0 minutes and 13 seconds read

Automount NTFS volume under Linux (Mint)

When automounting an NTFS volume under Linux (Mint) you can do this using the /etc/fstab file. dummy dummy dummy

$ sudo pico /etc/fstab

Add a line in the /etc/fstab file:

# custom mount point
/dev/sdb1 /media/windows-c ntfs-3g defaults 0 0

And take the mount into effect.

$ mount -a

May 24, 2013 0 minutes and 11 seconds read

Google Chrome not synchronizing extensions

When installing a fresh version of Chrome it may occur that all Bookmarks sync ok but the extensions not. The following solution worked for my system.

  • Open Google Chrome
  • Goto “Settings”
  • Open “Advanced Settings”
  • Check “Developer mode”
  • Press “Update extensions now”

May 16, 2013 0 minutes and 10 seconds read

Simple Helloworld verticle

Sourcecode:

package helloworld;

import org.vertx.java.core.Handler;
import org.vertx.java.core.http.HttpServerRequest;
import org.vertx.java.deploy.Verticle;

public class Server extends Verticle {

    public void start() {
        vertx.createHttpServer().requestHandler(new Handler<HttpServerRequest>() {
            public void handle(HttpServerRequest req) {
            req.response.headers().put("Content-Type", "text/html; charset-UTF-8");
            req.response.end("<html><body><h1>Hello from vert.x!</h1></body></html>");
            }
        }).listen(8080);
    }

}