viernes, enero 08, 2016

Container Object pattern. A new pattern for your tests.


If you search for a description of what Page Object is, you’ll find that The Page Object Pattern gives us a common sense way to model content in a reusable and maintainable way.

And also points that: Within your web app’s UI there are areas that your tests interact with. A Page Object simply models these as objects within the test code.
This reduces the amount of duplicated code and means that if the UI changes, the fix need only be applied in one place.

As you can see, Page Object applies to UI elements. We (the Arquillian community) has coined a new pattern following Page Object pattern logic called Container Object pattern.
You can think about Container Object as areas of a container (for now Docker container) that your test might interact with. For example some of these areas could be:
  • To get the host IP where container is running.
  • The bounded port for a given exposed port.
  • Any parameter configured inside the configuration file (Dockerfile) like a user or password to access to the service which the container exposes.
  • Definition of the containers.
A Container Object might contain an aggregation of more than one Container Object inside it. This effectively builds a relation ship (link) between containers.

An example of configuration parameters might be for example, in case of running a MySQL database in a container, it could be the user and password to access to database. 
Notice that nothing prevents you to generate the correct URL for accessing to the service from the test, or execute commands against container like retrieving an internal file.

And of course as Page Object does, Container Object gives you a way to build a model content that can be reused for several projects.

Before looking at how this pattern is implemented in Arquillian Cube, let’s go thorough an example:

Suppose all of your applications need to send a file to an FTP server. To write an integration/component test you might need a FTP server to send the file and check that the file was correctly sent.
One way to do this is using Docker to start a FTP server just before executing the test, then execute the test using this Docker container for FTP server, before stopping the container check that the file is there, and finally stop the container.

So all these operations that involves the FTP server and container could be joined inside a Container Object. This container object might contain information of:
  • Which image is used
  • IP and bounded port of host where this FTP server is running
  • Username and password to access to the FTP server
  • Methods for asserting the existence of a file
Then from the point of view of test, it only communicate with this object instead of directly hard coding all information inside the test.
Again as in Page Object, any change on the container only affects the Container Object and not the test itself.

Now let’s see how Arquillian Cube implements Container Object pattern with a very simple example:

Arquillian Cube and Container Object

Let’s see a simple example on how you can implement a Container Object in Cube. Suppose you want to create a container object that encapsulates a ping pong server running inside Docker.
The Container Object will be like a simple POJO with special annotations:

In previous example you must pay attention at next lines:
  1. @Cube annotation configures Container Object.
  2. A Container Object can be enriched with Arquillian enrichers.
  3. Bounded port is injected for given exposed port.
  4. Container Object hides how to connect to PingPong server.
@Cube annotation is used to configure this Container Object. Initially you set that the started container will be named pingpong and the port binding information for the container instance, in this case 5000→8080/tcp.
Notice that this can be an array to set more than one port binding definition.

Next annotation is @CubeDockerFile which configure how Container is created. In this case using a Dockerfile located at default classpath location. The default location is the package+classname, so for example in previous case, Dockerfile should be placed at org/superbiz/containerobject/PingPongContainer directory.
Of course you can set any other class path location by passing as value of the annotation. CubeDockerFile annotation sets the location where the Dockerfile is found and not the file itself.
Also this location should be reachable from ClassLoader, so it means it should be loaded from classpath in order to find it.

Any Cube can be enriched with any client side enricher, in this case with @HostIp enricher, but it could be enriched with DockerClient using @ArquillianResource as well.

Finally the @HostPort is used to translate the exposed port to bound port.
So in this example port value will be 5000. You are going to learn briefly why this annotation is important.

And then you can start using this container object in your test:

The most important thing here is that you need to set Container Object as a field of the class and annotate with @Cube.

It is very important to annotate the field with Cube, so before Arquillian runs the test, it can detect that it needs to start a new Cube (Docker container), create the Container Object and inject it in the test.

Notice that this annotation is exactly the same as used when you defined the Container Object.
And it is in this way because you can override any property of the Container Object from the test side. This is why @HostPort annotation is important, since port can be changed from the test definition, you need to find a way to inject the correct port inside the container object.

In this post I have introduced Container Object pattern and how can be used in Arquillian Cube. But this is only an small taste, you can read more about Arquillian Cube and Container Object integration at https://github.com/arquillian/arquillian-cube#arquillian-cube-and-container-object

Also a running examples can be found at https://github.com/arquillian/arquillian-cube/tree/master/docker/ftest-docker-containerobject

We keep learning,
Alex.

It's time to see what I can do, To test the limits and break through, No right, no wrong, no rules for me, I'm free! (Let It Go - Idina Menzel) 

Music: https://www.youtube.com/watch?v=moSFlvxnbgk

miércoles, noviembre 25, 2015

Java EE, Gradle and Integration Tests





In the last years Apache Maven has become the de-facto build tool for Java and Java EE projects. But from two years back Gradle is gaining more and more users. Following my previous post (http://www.lordofthejars.com/2015/10/gradle-and-java-ee.html), In this post you are going to see how to use Gradle for writing integration tests for Java EE using Arquillian.

Gradle is a build automation tool like Ant or Maven but introducing a Groovy-based DSL language instead of XML. So as you might expect the build file is a Groovy file. You can read in my previous post (http://www.lordofthejars.com/2015/10/gradle-and-java-ee.html) how to install Gradle.

To write integration tests for Java EE, the de-facto tool is Arquillan. If you want to know what Arquillian is, you can get a Getting Start Guide in (http://arquillian.org/guides/getting_started/) or in book Arquillian In Action.

To start using Arquillian, you need to add Arquillian dependencies, which comes in form of BOM. Gradle does not support BOM artefacts out of the box, but you can use dependency-management-plugin Gradle plugin to have support to define BOMs.

Moreover Gradle offers the possibility to add more test source sets apart from the default one which as in Maven is src/test/java and src/test/resources. The idea is that you can define a new test source set where you are going to put all integration tests. With this approach each kind of tests are clearly separated into different source sets. You can write Groovy code in Gradle script to achieve this or you can just use gradle-testsets-plugin which it is the easiest way to proceed.

So to register both plugins (dependency and testsets) you need to add next elements in build.gradle script file:

buildscript {
    repositories {
        jcenter()
    }
    dependencies {
        classpath "io.spring.gradle:dependency-management-plugin:0.5.3.RELEASE"
        classpath 'org.unbroken-dome.gradle-plugins:gradle-testsets-plugin:1.2.0'
    }
}

apply plugin: "io.spring.dependency-management"
apply plugin: 'org.unbroken-dome.test-sets'

Now it is time to add Arquillian dependencies. You need to add the Arquillian BOM, and two dependencies, one that sets that we are going to use Arquillian with JUnit, and another one that sets Apache TomEE application server as target for deploying the application during test runs.

build.gradle with Arquillian, TomEE and Java EE dependency might look like:

dependencyManagement {
    imports {
        mavenBom 'org.arquillian:arquillian-universe:1.0.0.Alpha1'
    }
}

dependencies {
    testCompile group: 'org.arquillian.universe', name: 'arquillian-junit', ext: 'pom'
    testCompile group: 'org.apache.openejb', name: 'arquillian-tomee-embedded', version:'1.7.2'
    testCompile group: 'junit', name: 'junit', version:'4.12'
    providedCompile group: 'org.apache.openejb',name: 'javaee-api', version:'6.0-6'


}

Finally you can configure the new integration test folder as source set by adding next section:

testSets {
    integrationTests
}

Where integrationTest is the name of the test set. testSets automatically creates and configures next elements:
  • src/integrationTests/java and src/integrationTests/resources as valid source set folders.
  • A dependency configuration named integrationTestsCompile which extends from testCompile, and another one called integrationTestRuntime which extends from testRuntime.
  • A Test task named integrationTests which runs the tests in the set.
  • A Jar task named integrationTestsJar which packages the tests. 
Notice that you can change the integrationTests to any other value like intTests and Gradle would configure previous elements automatically to the value set it inside testSets, such as src/intTests/java or for example the test task would be called intTests.

Next step is creating the integration tests using Arquillian inside integrationTests test set. For example an Arquillian test for validating that you can POST a color in a REST API and it is returned when GET method is called, would look like:

You can now run integration tests by simply executing gradlew integrationTests

You'll notice that if you run gradlew build, the integration test task is not run. This happens because task is not registered within the default build lifecycle. If you want to add integrationTests task to be executed automatically during build you need to add next lines:

check.dependsOn integrationTest
integrationTest.mustRunAfter test

Ensure that integration tests are run before the check task and that the check task fails the build if there are failing integration tests and also ensures that unit tests are run before integration tests. This guarantees that unit tests are run even if integration tests fails.

So now when you run gradlew build, the integration tests are going to be executed as well.

And finally, what's happen if you are running JaCoCo plugin for code coverage? You will get two JaCoCo files, one for the unit test executions and another one for the integrationTests execution. But probably you want to see an aggregated code coverage report of both runs into one file, so you can inspect the code coverage degree of the application after the execution of all kind of tests. To achieve it you only need to add next task:

task jacocoRootTestReport(type: JacocoReport) {
    sourceSets sourceSets.main
    executionData files([
            "$buildDir/jacoco/test.exec",
            "$buildDir/jacoco/integrationTests.exec"
    ])
    reports {
        xml.enabled false
        csv.enabled false
    }    
}

In this case you are creating a task which aggregates the coverage results of test.exec file (which comes from unit tests) and integrationTests.exec which comes from integration tests.

And to generate the reports you need to explicitly call the jacocoRootTestReport task when you run Gradle

So it is so simple to write a Gradle script for running Java EE tests and more important the final script file looks very compact and readable without being tight to any static convention at all.

We keep  learning,
Alex.
There must be more to life than this, There must be more to life than this, How do we cope in a world without love (There Must Be More To Life Than This - Freddie Mercury - Michael Jackson)

miércoles, octubre 07, 2015

Gradle and Java EE


In the last years Apache Maven has become the de-facto build tool for Java and Java EE projects. But from two years back Gradle is gaining more and more users. In this post you are going to see how to use Gradle for Java EE projects.

Gradle is a build automation tool like Ant or Maven but introducing a Groovy-based DSL language instead of XML. So as you might expect the build file is a Groovy file.

There are different ways to install Gradle, but for me the best way is using sdkman tool. To install sdkman tool simply run:

$ curl -s get.sdkman.io | bash

After that you can init sdkman by running:

$ source "$HOME/.sdkman/bin/sdkman-init.sh"

With sdkman installed, installing Gradle is as easier as running:

$ sdk install gradle

Now you can start creating the build script. The first thing to do is creating a settings.gradle where in this case we are going to set the name of the project.

This file is also used in case of multiple module projects.

Last file you might need is one called build.gradle which manages all the build process.


Notice that the first line indicates that what you are going to build is a war project.  Then project properties are set like the group, version, description or Java compilation options. Finally only one dependency is required and with provided scope since the implementation is provided by the application server.

Note that providedCompile scope is only available if you are using the war plugin. If you are using another plugin like java, then you will need to implement this function by yourself (at least at the time of writing this post with Gradle  2.7).

And that's all, pretty compact, only 16 lines and no verbose information. Of course, now you will need to add more dependencies like JUnit or Arquillian with testCompile scope or any other extra library required in your code like the well known apache-commons dependency; But this is an story for another post.

We keep learning,
Alex.

Sun's in your eyes the heat is in your hair. They seem to hate you. Because you're there.  (Wonderful Life - Black)


martes, agosto 11, 2015

Arquillian Cube: Write Tests Once, Run Them Everywhere



Arquillian Cube is an Arquillian extension that can be used to manage Docker containers from Arquillian. Basically it starts all Docker containers required for your tests, deploys the application (or micro-application) which can be Java based or not, runs the tests and finally stops all of them.

Thanks of Arquillian Cube you can run your integration tests from your local IDE in similar situation as in production environment since in both cases everything is running inside Docker.

But you can go one step forward and you can instruct Arquillian Cube to not start Docker container instances locally (or inside your local boot2docker) but start them in external locations such as your preproduction infrastructure.

Thanks of Digital Ocean that has provided us a free account with some money, we can show you in next screencast how by simply changing one attribute (which could be automated with maven-resources-plugin or just using system properties), we are running the same test against local Docker instance or remotely to Digital Ocean infrastructure.

You can read more about Arquillian and Arquillian Cube in book Arquillian In Action (www.manning.com/sotobueno).


We keep learning,
Alex.
You’re a shooting star I see, A vision of ecstasy, When you hold me, I’m alive, We’re like diamonds in the sky (Diamonds - Rihanna)
Music: https://www.youtube.com/watch?v=lWA2pjMjpBs


lunes, agosto 03, 2015

Arquillian in Action goes MEAP


Currently  I am co-writing Arquillian in Action book with my colleague Jason Porter. Last week the book just entered into MEAP stage.

Arquillian in Action teaches you how to to build in-container tests using Arquillian. This practical hands-on guide begins with showing you how to find and squash your first bug. You'll move on to building persistence tests, and then discover how to write tests for front-end and RESTful services. Using carefully-designed examples, the book shows you how to write integration tests for Java EE, Spring, and Docker. Along the way, you'll also learn how to build functional, infrastructure, performance, and security tests.

You can visit http://www.manning.com/sotobueno, read the first chapter for free or you can buy it and start reading the first three chapters of the book.

It is time to start zapping all these bugs with Arquillian.

We keep learning,
Alex.

Algo lo que me invade, todo viene de dentro, Nunca lo que me sacie, siempre quiero, lobo hambriento. (Por la boca vive el pez - Fito & Fitipaldis)

Music:  https://www.youtube.com/watch?v=iUXs4Nt3Y7Y

miércoles, abril 01, 2015

Apache Mesos + Marathon and Java EE


Apache Mesos is an open-source cluster manager that provides efficient resource isolation and sharing across distributed applications or frameworks.

Apache Mesos abstracts CPU, memory, storage, and other compute resources away from machines (physical or virtual), enabling fault-tolerant and elastic distributed systems to easily be built and run effectively. It uses dynamic allocation of applications inside machines.

In summary Apache Mesos is composed by master and slaves. Masters are in charge of distributing work across several slaves and knowing the state of each slave. You may have more than one master for fault-tolerant.

And then we have the slaves which are the responsible of executing the applications. Slaves isolate executors and tasks (application) via containers (cgroups). 

So each slave offers its resources and Apache Mesos is in charge of schedule which slave will execute it. Note that each slave may execute more than one task if it has enough resources to execute it.



For example let's say that an Slave has 4 CPUs (to simplify I am not going to take into account other parameters), then it could execute 1 task of 4 CPU, 2 tasks of 2CPUs, ...

But Apache Mesos only manages resources, but for building a PaaS we need something more like service discovery or scaling features. And this is what Marathon does.

Marathon is a framework that runs atop of Apache Mesos and offers:

  • Running Linux binary
  • Cluster-wide process supervisor
  • Service Discovery and load balancing (HAProxy)
  • Automated software and hardware failure handling
  • Deployment and scaling
  • REST friendly

But one of the main advantages of using Marathon is that it simplifies and automates all those common tasks.

So main task of Marathon is deploy an application to different salves, so if one salve fails there are other slaves to serve incoming communications. But moreover Marathon will take care of reallocating the application to another slave so the amount of slaves per application is maintained constant. 



Installing Apache Mesos and Marathon in a developer machine is as easy as, having VirtualBox, Vagrant and git installed.

Cloning next repo:


And simply run vagrant-up command from the directory:

cd playa-mesos
vagrant up

First time it will take some time because it need to download several components.

After that you can check that it is correctly installed by connecting to Mesos and Marathon Web Console. http://10.141.141.10:5050 and http://10.141.141.10:8080

Next step is installing HAProxy. Although it is not a requirement HAProxy is "required" if you want to do Service Discovery and Load Balancing.

Run vagrant ssh.

Install HAProxy

sudo apt-get install haproxy

Download haproxy-marathon-bridge script:

chmod 755 haproxy-marathon-bridge

./haproxy_marathon_bridge localhost:8080 > haproxy.cfg
haproxy -f haproxy.cfg -p haproxy.pid -sf $(cat haproxy.pid)

And this configures HAproxy. To avoid having to run this command manually for every time topology change you can run:

./haproxy_marathon_bridge install_haproxy_system localhost:8080 

which installs the script itself, HAProxy and a cronjob that once a minute pings one of the Marathon servers specified and refreshes HAProxy if anything has changed.

And that's all, now we have our Apache Mesos with Mesosphere and HAProxy installed. Now it is time to deploy the Java EE application server. In this case we are going to use Apache TomEE.

The only thing we need to do is sending a JSON document as POST to http://10.141.141.10:8080/v2/apps 

{
  "id": "projectdemo",
  "cmd": "cd apache-tomee-plus* && sed \"s/8080/$PORT/g\" < ./conf/server.xml > ./conf/server-mesos.xml && ./bin/catalina.sh run -config ./conf/server-mesos.xml",
  "mem": 256,
  "cpus": 0.5,
  "instances": 1,
  "ports":[10000],
  "constraints": [
    ["hostname", "UNIQUE"]
  ],
  "uris": [
  ]
}

This JSON document will make Marathon to deploy the application in one node. Let's explain each attributes:

id: is the id of the application, not much secret here.

cmd: the command that will execute when node is chosen an ready. In this case note that we are creating a server-mesos.xml file which is a modified version of server.xml file but replacing 8080 port to $PORT var. For now is enough. Finally it starts TomEE with server-mesos.xml configuration file.

mem: Memory that will require in the node.

cpus: Cpu resources that will require in the node.
instances: number of nodes that we want to replicate this application. In this case only one because we are running locally.

ports: which ports will group all application instances. Basically this port is used by HAProxy to route to the correct instance. We are going to explain deeply in next paragraph.

constraints: constraints control where apps run to allow optimizing for fault tolerance or locality. In this case we are setting that each application should be in a different slave. With this approach you can avoid port collision.

uris: Sets the URI to execute before executing the cmd part. In case of a known compressed algorithm, it is automatically uncompressed. For this reason you can do a cd command in cmd directly without having to uncompress it manually.

So let me explain what's happening here or what Mesosphere does:

First of all reads the JSON document and inspect which slave has a node that can process this service. In this case it only needs to find one. (instances = 1).

When it is found, then the uri element is downloaded, uncompressed and then executes the commands specified in cmd attribute in current directory.
And that's all.

But wait what is ports and $PORT thing?

$PORT is a random port that Mesosphere will assign to a node to communicate with. This port is used to ensure no two applications can be run using Marathon with overlapping port assignments.

But also it is used for Service Discovery and Load Balancing by running a TCP proxy on each host in the cluster, and transparently forward a static port on localhost to the hosts that are running the app. That way, clients simply connect to that port, and the implementation details of discovery are completely abstracted away.

So the first thing we need to do is modifying the configuration of the TomEE to start at random port assigned by Marathon, for this reason we have created a new server.xml file and setting listening port to $PORT.

So if port is random, how a client may connect if it doesn't know in which port is started? And this is the ports attribute purpose. In this attribute we are setting that when I connect to port 10000 I want to connect to the application defined and deployed to any slave and independently of the number of instances.

Yes it may be a bit complicated but let me explain with a simple example:

Let's say I have the same example as before but with two instances (instances = 2). Both TomEE instances will be started in two different slaves (so in different nodes) and in different ports. Let's say 31456 and 31457. So how we can connect to them?

Easy. You can use the IP of Marathon and the random port (http://10.141.141.10:31456/) which you will access to that specific server, or you can use the global defined port (http://10.141.141.10:10000/) which in this case HAProxy will route to one of instances (depending on load balancing rules).

Note this has a real big implication on how we can communicate between applications inside Marathon, because if we need internal communication between applications that are deployed in Marathon, we only need to know that global port, because the host can be set to localhost as HAProxy will resolve it. So from within Marathon application we can communicate to TomEE by simply using http://localhost:10000/ as HAProxy will then route the request to a host and port where an instance of the service is actually running. In next picture you can see the dashboard of Marathon and how the application is deployed. Note that you can see the IP and port of deployed application. You can access by clicking on it or by using Marathon IP (the same as provided in that link) but using the port 10000. Remember that HAProxy is updated every minute so if it works by using random port and not using port 10000 probably you need to wait some time until HAProxy database is refreshed.


And that's all, as you may see Apache Mesos and Marathon is not as hard as you may expect at first.

Also note that this is a "Hello World" post about Mesos and Java EE, but Mesos and Mesosphere is much more than this like healthy checks of the services, running Docker containers, Artifact Storage or defining dependencies, but I have found that running this simple example, helps me so much clarifying the concepts of Mesosphere and it was a good point of start for more complex scenarios.

We keep learning,
Alex.
Dilegua, o notte!, Tramontate, stelle!, Tramontate, stelle!, All'alba vincerò!, Vincerò! Vincerò! (Nessun dorma - Giacomo Puccini)

miércoles, marzo 04, 2015

Restful Web Service Guide


Nowadays more and more projects are developed using the tuple AngularJs in frontend + Java EE (or Spring Framework) in backend. The communication between AngularJs and Java EE is done by using Restful Web Services

In my company this tuple is implemented in every project and we are several teams working on different projects. So it seems clear that it would have sense that all Restful Web Services should be done in similar way. For this reason we (the architecture team) decided to create a Restful Web Service guide where all teams could base their API design. In this document we mention basic concepts of Rest, but also how to internationalize a Rest API, Pagination, Security with Json Web Tokens or Http Error codes.

This guide has been released under CC license and is published in github. You can watch it without any problem, send a PR with any improvement or open an issue to discuss anything.


We keep learning,
Alex.

It might seem crazy what I'm about to say, Sunshine she's here, you can take away, I’m a hot air balloon, I could go to space ,With the air, like I don't care baby by the way (Happy - Pharrell Williams)

Music: https://www.youtube.com/watch?v=y6Sxv-sUYtM

Donate If You Can and Find Post Useful