Archive for the ‘brocco’ Category

Handling multiple verticle deployment
April 4, 2014

Every Vert.x module needs a single point of start.
Once your application has many verticles interacting you’ll need one verticle to start them all, one verticle to find them, one verticle to bring them all and in the darkness bind them (I’m sorry).
For this particular task I prefer to use javascript. I tend to think of this verticle as the start script of my application, so I like it to be easy to write and I found the javascript syntax to be a good fit on this.

My deployment verticle

I usually name it app-deployer.js and I place it in src/main/javascript (I’ll explain below how to add it to Maven).

var container = require("vertx/container")
var console = require("vertx/console")
var config = container.config;

var skipDeploy;
if (config.skipDeploy) {
  skipDeploy = config.skipDeploy;
} else {
  skipDeploy = [];
}

const verticles = [
  {
    name : "con.locademiaz.vertx.FirstVerticle",
    instances : 1,
    config : {
      foo_param : config.bar_param
    }
  }
];

deployVerticles(verticles, 0);

function deployVerticles(verticles, verticleIndexToDeploy) {
  if (verticleIndexToDeploy < verticles.length) {
    const verticle = verticles[verticleIndexToDeploy];
    const verticleName = verticle.name;
    if (skipDeploy.indexOf(verticleName) == -1 ) {
      container.deployVerticle(
        verticleName,
        verticle.instances,
        verticle.config,
        function(err, deployID) {
          if (!err) {
            console.log("[Ok] " + verticleName);
            deployVerticles(verticles, verticleIndexToDeploy + 1);
          } else {
            console.log("[Fail] " + verticleName + " -> " + err.getMessage());
          }
        }
      )
    } else {
      console.log("[Skip] " + verticleName);
      deployVerticles(verticles, verticleIndexToDeploy + 1);
    }
  }
}

In this file you can do all kinds of tricks.
One of my preferred ones is to add a list of blacklisted verticles. This is useful for testing because you can deploy this file, getting your all system deployed, and mock some behavior inside your test.
Also, as I like to keep my external configuration lean, it is here where I manipulate what is passed by the command line and adapt it to each verticle needs.

Extending your Maven configuration

Following what is explained in my previous post this is how you add your verticle deployer to your Maven configuration

pom.xml

Add the resource folder

<project>
  ...
  <build>
    ...
    <resources>
      ...
      <resource><directory>src/main/javascript</directory></resource>
      ...
    </resources>
    ...
  </build>
  ...
</project>

And now, because I’m a control freak, I don’t like unnecessary files ends up in the jar for my project, so I exclude them from the package as follows:

<project>
  ...
  <build>
    ...
    <plugins>
      ...
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-jar-plugin</artifactId>
        <version>2.4</version>
        <configuration>
          <excludes>
            <exclude>app-deployer.js</exclude>
          </excludes>
        </configuration>
      </plugin>
      ...
    </plugins>
    ...
  </build>
  ...
</project>

And that’s it, now you have a nice entry point for your module.
Enjoy.
.

Vert.x Java project – Quick start
April 3, 2014

After having 41 successful-n-productive™ Vert.x systems running, I have distilled a few practices which makes worth to share.

Building environment

I’ve decided to go with Maven for managing dependencies and build cycle. Vert.x has support for Gradle but I dropped this option because I just wanted a simple descriptive language for my project, instead of a full imperative language for this purpose. Nothing against Gradle though.

Vert.x modules

Vert.x recommends to organize your application as modules. Beside all the technical benefits of this practice (classloader isolation, dependency management, etc), I would also like to add that this is a great way to define different areas of development across your team. This, along with a clear document of the services provided and exposed by the modules within its interfaces, will help you to isolate different application concerns as the building blocks for the whole system.

Initial setup

Vert.x has a Maven Archetype for getting started, but IMHO it doesn’t do well with Maven files, and it also generates a single project containing examples for every supported language. BTW, I’ve sent a pull request for this, that has never discussed.
This post will assume you have some knowledge of Maven, its structure and usage.

pom.xml

You can read an in depth explanation of the structure of this file here (this is not yet ready)

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.locademiaz.vertx</groupId>
  <artifactId>quick-start</artifactId>
  <version>0.1-SNAPSHOT</version>
  <packaging>jar</packaging>

  <dependencies>
    <dependency>
      <groupId>io.vertx</groupId>
      <artifactId>vertx-platform</artifactId>
      <version>2.1M2</version>
      <scope>provided</scope>
    </dependency>
    <dependency>
      <groupId>io.vertx</groupId>
      <artifactId>testtools</artifactId>
      <version>2.0.2-final</version>
      <scope>test</scope>
    </dependency>
  </dependencies>

  <build>
    <resources>
      <resource>
        <directory>src/main/resources</directory>
        <filtering>true</filtering>
      </resource>
      <resource>
        <directory>src/main/js</directory>
      </resource>
    </resources>
    <testResources>
      <testResource>
        <directory>src/test/resources</directory>
        <filtering>true</filtering>
      </testResource>
    </testResources>

    <plugins>
      <plugin>
         <groupId>org.apache.maven.plugins</groupId>
         <artifactId>maven-compiler-plugin</artifactId>
         <version>2.5.1</version>
         <configuration>
           <source>1.7</source>
           <target>1.7</target>
         </configuration>
      </plugin>
      <plugin>
        <artifactId>maven-assembly-plugin</artifactId>
        <version>2.4</version>
        <configuration>
          <outputDirectory>${project.build.directory}/mods</outputDirectory>
          <finalName>${module.name}</finalName>
          <appendAssemblyId>false</appendAssemblyId>
          <descriptors>
            <descriptor>src/main/assembly/mod.xml</descriptor>
          </descriptors>
        </configuration>
        <executions>
          <execution>
            <id>make-assembly</id>
            <phase>package</phase>
            <goals>
              <goal>single</goal>
            </goals>
          </execution>
        </executions>
      </plugin>
      <plugin>
        <groupId>io.vertx</groupId>
        <artifactId>vertx-maven-plugin</artifactId>
        <version>2.0.1-final</version>
      </plugin>
    </plugins>
  </build>
  <properties>
    <module.name>${project.groupId}~${project.artifactId}~${project.version}</module.name>
  </properties>
</project>
mod.xml

Vert.x defines a structure for its modules, so, below is a Maven Assembly definition for building it. In concordance with the pom.xml defined above, this must be placed in the src/main/assembly directory.

<?xml version="1.0" encoding="UTF-8"?>
<assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2 http://maven.apache.org/xsd/assembly-1.1.2.xsd">

  <id>mod</id>

  <formats>
    <format>zip</format>
    <format>dir</format>
  </formats>
  <dependencySets>
    <dependencySet>
      <useProjectArtifact>false</useProjectArtifact>
      <outputDirectory>lib/</outputDirectory>
      <scope>runtime</scope>
      <fileMode>664</fileMode>
    </dependencySet>
  </dependencySets>

  <includeBaseDirectory>false</includeBaseDirectory>

  <fileSets>
    <fileSet>
      <directory>${project.build.outputDirectory}</directory>
      <outputDirectory>/</outputDirectory>
      <includes>
        <include>**</include>
      </includes>
    </fileSet>
  </fileSets>
</assembly>
Your first verticle

Now we have everything setup to start coding. Create a FirstVerticle.java file inside the src/main/java/com/locademiaz/vertx directory with the following content:

package com.locademiaz.vertx;

import org.vertx.java.platform.Verticle;

public class FirstVerticle extends Verticle {

    @Override
    public void start() {
        container.logger().info("Your first verticle has been started!");
    }
}
mod.json

The final part of a Vert.x module is its descriptor. You can find a comprehensive list of its fields here. Place this file in the src/main/resources directory

{
    "main":"com.locademiaz.vertx.FirstVerticle",
    "deploys":"${module.name}",
}

Running your module

Development phase

As you can see in the pom.xml file above the vertx-maven-plugin is configured in lines 72-76. Having this configured, allows you to run, directly from your source code, Vert.x with your module just in place. For doing so just run:

$ mvn clean package vertx:runMod

et voilà, you should see the message logged into the system console

Productive phase

As presented here, the .zip generated in the target/mods by the command

$ mvn clean package

is ready to be deployed. You can drop it into your Nexus repository, or into your local maven structure, or you can also use the handy runzip option:

$ vertx runzip target/mods/com.locademiaz.vertx~quick-start~0.1-SNAPSHOT.zip

In the upcoming entries you can expect more insights about handling deployment, configuration, vert.x packaging, testing, continuous integration and any other shenanigan I encounter in this pleasant trip. Stay tuned.