Eclipse Yoxos Services Downloads Blogs About
Home > Blogs >

Posts Tagged ‘jetty’

on Jan 17th, 2012Continuous Integration Tests for REST APIs with Maven, Jetty and restfuse

As you might know from previous posts, most of my work time has something to do with the development of REST based systems. The systems we develop are mostly written in Java. To ensure that a system works, we have a step in our continuous integration process that executes integration tests before automated deployment is launched. With this short post I’d like to show you our setup for these integration tests because when I searched a few months ago the results were rare.

We write integration tests for REST systems with JUnit and restfuse. Check this post for a how-to on restfuse. Thanks to the Maven surefire plugin we can simply execute these tests in our maven build. Here is the build and dependency section of the test module’s pom.

<build>
  <plugins>
    <plugin>
      <groupId>org.apache.maven.plugins</groupId>
      <artifactId>maven-surefire-plugin</artifactId>
      <version>2.9</version>
      <executions>
        <execution>
          <id>test</id>
          <phase>test</phase>
          <configuration>
            <testClassesDirectory>${project.build.outputDirectory}</testClassesDirectory>
          </configuration>
          <goals>
            <goal>test</goal>
          </goals>
        </execution>
      </executions>
    </plugin>
    ...
  </plugins>
</build>
 
<dependencies>
  <dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.8.1</version>
    <scope>test</scope>
  </dependency>  
  <dependency>
    <groupId>com.restfuse</groupId>
    <artifactId>com.eclipsesource.restfuse</artifactId>
    <version>1.0.0</version>
  </dependency>
</dependencies>

Most of our Java-REST applications ship as war files.  So, at this stage the question becomes, “How can I test the war file I just built?” One answer is to hot deploy the war file and run the tests against it. But, for a hot deployment we need a server running tomcat (or another servlet container), right? Actually, we don’t icon wink Continuous Integration Tests for REST APIs with Maven, Jetty and restfuse . We can simply embed a Jetty plugin into our maven build, start it and deploy our war file using the Maven Jetty plugin. The related section in the pom looks like this:

<build>
  <plugins>
    ...
    <plugin>
      <groupId>org.mortbay.jetty</groupId>
      <artifactId>maven-jetty-plugin</artifactId>
      <version>${jetty-version}</version>
      <configuration>
        <scanIntervalSeconds>10</scanIntervalSeconds>
        <stopKey>foo</stopKey>
        <stopPort>9090</stopPort>
        <contextPath>/</contextPath>
        <tmpDirectory>/tmp/work/</tmpDirectory>
        <webApp>/tmp/test.war</webApp>
        <daemon>true</daemon>
        <reload>manual</reload>
      </configuration>
      <executions>
        <execution>
          <id>start-jetty</id>
          <phase>test-compile</phase>
          <goals>
            <goal>deploy-war</goal>
          </goals>
        </execution>
        <execution>
          <id>stop-jetty</id>
          <phase>verify</phase>
          <goals>
            <goal>stop</goal>
          </goals>
        </execution>
      </executions>
    </plugin>  
    ...    
  </plugins>
</build>

It is important that we deploy the war file before the actual test phase, in our example, during test-compile. To make this work we need to copy the new war file into the configured directory before we run the maven build. This can be accomplished with a simple shell script.  The following snippet shows how it looked for our jenkins job:

rm -rf /tmp/work
mkdir /tmp/work
cp $WORKSPACE/../job/**/*.war /tmp/test.war

A few last points.  In our setup we split the integration test build from the main build but you can merge them together as well. And, when using restfuse an important thing to keep in mind is that you need to configure the port to be the same as the one jetty uses to run the tests.

That’s it – short but efficient. Maybe you have a similar approach to share in a comment with us?

followme Continuous Integration Tests for REST APIs with Maven, Jetty and restfuse

on Aug 12th, 2011How to build a cluster with Jetty / OSGi

In this blog post I describe how to set up a cluster node with an embedded Jetty Server inside Equinox.

Basically I followed the instructions available at the Jetty Wiki page Session Clustering Using a Database [1].

There are two Jetty configuration files involved:

  • /etc/jetty.xml defining a JDBCSessionIdManager
  • /WEB-INF/jetty-web.xml defining a JDBCSessionManager

The main jetty.xml resides in the folder etc of the jetty.home.bundle which itself is a fragment of org.eclipse.jetty.osgi.boot. The jetty.osgi.boot bundle is provided by the Jetty team and is responsible for bootstrapping Jetty in an OSGi environment.

The main configuration file contains the JDBCSessionIdManager definition using a H2 database:

 <Set name="sessionIdManager">
  <New id="jdbcidmgr" class="org.eclipse.jetty.server.session.JDBCSessionIdManager">
    <Arg>
      <Ref id="Server" />
    </Arg>
    <Set name="workerName">
      <SystemProperty name="worker.name" default="primary" />
    </Set>
    <Call name="setDriverInfo">
      <Arg>org.h2.Driver</Arg>
      <Arg>jdbc:h2:tcp://localhost:9101/sessions</Arg>
    </Call>
    <Set name="scavengeInterval">60</Set>
  </New>
</Set>
<Call name="setAttribute">
  <Arg>jdbcIdMgr</Arg>
  <Arg>
    <Ref id="jdbcidmgr" />
  </Arg>
</Call>

Note: To reuse the configuration in multiple cluster nodes I use a SystemProperty tag to give every node a unique “worker.name”. The database configuration is hardwired to a local H2 database.

With additional system properties I can tell the Jetty bootstrapper where to look for the global Jetty configuration and which port the Jetty instance should bind to:

-Dworker.name=primary
-Djetty.port=18081
-Djetty.home.bundle=com.eclipsesource.cluster.jetty.home.bundle

To enable the Jetty server to load the H2 database drivers I added a dynamic import directive via the fragment org.eclipse.jetty.serverdynamic.import:

Fragment-Host: org.eclipse.jetty.server;bundle-version="7.4.2"
DynamicImport-Package: *

The web application specific configuration /WEB-INF/jetty-web.xml is located in the web bundle, com.eclipsesource.cluster.jetty.demo.webbundle. This configuration file contains the JDBCSessionManager definition.

<Configure class="org.eclipse.jetty.webapp.WebAppContext">
  <Get name="server">
    <Get id="jdbcIdMgr" name="sessionIdManager" />
  </Get>
  <Set name="sessionHandler">
    <New class="org.eclipse.jetty.server.session.SessionHandler">
      <Arg>
        <New class="org.eclipse.jetty.server.session.JDBCSessionManager">
          <Set name="idManager">
            <Ref id="jdbcIdMgr" />
          </Set>
        </New>
      </Arg>
    </New>
  </Set>
</Configure>

Note: “jdbcIdMgr” is a Reference to the jetty.xml from jetty.home.bundle.

If you want to try it out yourself, the code is available at GitHUB [2].

Note: The bundle com.eclipsesource.cluster.h2 contains an Eclipse launch configuration to start a local H2 database which is needed to run the example.

[1] http://wiki.eclipse.org/Jetty/Feature/Session_Clustering_Using_a_Database
[2] https://github.com/eclipsesource/com.eclipsesource.cluster

on Dec 15th, 2010How do you run your RAP application today?

Hi,

We’d like to know more about RAP in the wild. Please take a moment and answer the question that follows below. We will publish the results of this anonymous poll later on this blog, and we’ll use them to influence the direction of the research work of the Sovereign project.

Thanks for your time.

How do you run your RAP application today?

Create an online survey quiz or web poll

on Oct 2nd, 2009Executable WARs with Jetty

Today I want to talk about one of the younger members in the Eclipse family: Jetty. It is great to have such an interesting project on board and it is yet another example of how Eclipse has become more than just an IDE.

What I wanted to with jetty was to create an executable, standalone and self-contained WAR. I first encountered this concept in Hudson. The hudson.war contains an embedded Winstone servlet container, which makes it possible to run the application by executing

java -jar hudson.war

This makes test driving the application really simple. The idea was to do the same with Jetty. Embedding the Jetty runtime in the war proved to be the easy part, as it was just a matter of declaring the jetty dependencies in the maven pom.xml.

The tricky part was telling jetty where to find the war-file to serve. My first try was to hardcode the filename, but that left a foul aftertaste. Finding a solution took quite some time, which is why I am posting this for future reference. This is the Main-Class used to bootstrap Jetty (adapted from the Wicket quickstart archetype):

import org.mortbay.jetty.Connector;
import org.mortbay.jetty.Server;
import org.mortbay.jetty.bio.SocketConnector;
import org.mortbay.jetty.webapp.WebAppContext;
 
public class Start {
 
  public static void main(String[] args) throws Exception {
    Server server = new Server();
    SocketConnector connector = new SocketConnector();
 
    // Set some timeout options to make debugging easier.
    connector.setMaxIdleTime(1000 * 60 * 60);
    connector.setSoLingerTime(-1);
    connector.setPort(8080);
    server.setConnectors(new Connector[] { connector });
 
    WebAppContext context = new WebAppContext();
    context.setServer(server);
    context.setContextPath("/");
 
    ProtectionDomain protectionDomain = Start.class.getProtectionDomain();
    URL location = protectionDomain.getCodeSource().getLocation();
    context.setWar(location.toExternalForm());
 
    server.addHandler(context);
    try {
      server.start();
      System.in.read();
      server.stop();
      server.join();
    } catch (Exception e) {
      e.printStackTrace();
      System.exit(100);
    }
  }
}

The interesting bit is the getProtectionDomain()/getCodeSource() part, which tells us the location of the war-file. That’s all there is to it. Presto, executable web-application powered by Jetty in jar.

Edit: Added the import statements as per Tim’s suggestion.

© EclipseSource 2008 - 2011