Tutorial – Docker, JPA and Testing

Hi,

a few weeks ago I attended the BED – Con. One of the talks I listened to, was about Docker (given by Dr. Halil-Cem Gürsoy).

One of the ideas that came directly to my mind was, to use docker for creating separate instances of the finally used database for tests that can’t use databases like H2 (For example, when using some specific features).

In this post I will show you how to use Docker for providing separated database instances and instruct JPA to use this connection.

Requirements

  1. Docker 0.9+ installed and configured to listen on the http interface (see here for instructions)
    • If you’re running on MacOS or windows, please look into the specific instructions for your platform (MAC / Windows)
  2. Java 1.6+
  3. Gradle 1.8+
  4. postgres as docker image available (I used the one from the http://docs.docker.io/examples/postgresql_service/ example provided by docker)

The “project”

Just persisting a book into the database

Dependencies

We need the following dependencies

The jersey libraries are required for easy access to the rest interface of Docker.

Now let’s

Getting wet

and implement our simple data model for a book with a just a name

As a next step we need the persistence.xml for the test cases.

As you might have noticed, I omitted all properties that are related with the connection to the database, eg.javax.persistence.jdbc.url. These properties will be set during the test.

Before we can implement the test we need to create access to dockers rest interface. This access will enable us to

  • create and start a container,
  • get the IP address of this container and
  • stop the container after the test.

The following class will serve all methods we need.

Hint: Please adopt the PORT and SERVER property to your needs

I implemented very simple and not complete data objects for easier access to Dockers interface, but omitted them here for the sake of brevity (You can find them here : https://github.com/coders-kitchen/emdote).

Having the class Docker in place, we can now start writing the test.

The test starts first a container and retrieveis the ip adress of this container

Now we can create the entity manager with the required properties

Finally we can create a transaction, persist some books, commit everything and stop the container.

Note: I added the sleep to have the chance to look into the containers database to see if everything has worked well. You could also remove the Docker.stop(container) call. But then you must stop the container by hand.

The complete test class

When executing the test we

  1. Create and run a new docker container
  2. Retrieve it’s IP
  3. Create a entity manager with the required properties to access the database inside of the container
  4. Add two books
  5. And stop the container

You will notice, that the test will wait during the creation of the entity manager. This is because postgres needs to start up first.

The code for this tutorial can be found at https://github.com/coders-kitchen/emdote.

Final note

I implemented the request / response entities for this example on my own. But  I recommend to use (Docker Java) which provides access to the most of Dockers rest api features.

 

 
3 Kudos
Don't
move!

2 thoughts on “Tutorial – Docker, JPA and Testing

  1. Hi !

    I want to thanks you for this tutorial.

    I’m currently using JPA (EclipseLink) and PostGres but I don’t really understand, what your tutorial is used for ?
    For a school project, I ‘ve to create a docker img , with two containers (Postgres DB + executable JAR) and I want to ask you
    if I can use it in order to create the docker img ?

    If this is not the case, can you explain me how can I do it ?

    Thanks !


    1. Hi Maxime,

      in this small tutorial post I wanted to share how can control docker from a unittest level to get rid of the awkward infrastructure dependencies that are usually needed.

      What I get from your information is, that you want / need to have 1 docker container for Postgres and one with an executable jar, that accesses the Postgres one.

      This is not the intention of the post, what you need is to create the Postgres image ( or use an existing one) that is populated with your schema(s). The image itself must be configured to expose the postgres port 5672.
      After this is done you need a second image which has provisioned your executable jar. Here it is important to either have a fixed name for the postgres-server, eg. postgres, or an environment variable that can be set on startup of the container.

      This is important as you need to tell docker under which name a certain container should be linked to another container.
      It means that you can do it like this:

      docker run -d –name postgres-server postgres
      docker run -d –link postgres-server myExecutableJar

      do so, the latter container has access to the first one via the name postgres-server and exposed port 5672

      I hope this helps

      Cheers

      Peter


Leave a Reply

Your email address will not be published. Required fields are marked *