<chapter id="RESTEasy_Embedded_Container">
<title>Embedded Containers</title>

    <para>RESTEasy has a few different plugins for different embedabble HTTP and/or Servlet containers if use RESTEasy in
    a test environment, or within an environment where you do not want a Servlet engine dependency.</para>
    <section>
        <title>Undertow</title>
        <para>
            Undertow is a new Servlet Container that is used by WildFly (JBoss Community Server).  You can embed
            Undertow as you wish.  Here's a a test that shows it in action.
<programlisting><![CDATA[
import io.undertow.servlet.api.DeploymentInfo;
import org.jboss.resteasy.plugins.server.undertow.UndertowJaxrsServer;
import org.jboss.resteasy.test.TestPortProvider;
import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;

import javax.ws.rs.ApplicationPath;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.core.Application;
import java.util.HashSet;
import java.util.Set;

/**
 * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
 * @version $Revision: 1 $
 */
public class UndertowTest
{
   private static UndertowJaxrsServer server;

   @Path("/test")
   public static class Resource
   {
      @GET
      @Produces("text/plain")
      public String get()
      {
         return "hello world";
      }
   }

   @ApplicationPath("/base")
   public static class MyApp extends Application
   {
      @Override
      public Set<Class<?>> getClasses()
      {
         HashSet<Class<?>> classes = new HashSet<Class<?>>();
         classes.add(Resource.class);
         return classes;
      }
   }

   @BeforeClass
   public static void init() throws Exception
   {
      server = new UndertowJaxrsServer().start();
   }

   @AfterClass
   public static void stop() throws Exception
   {
      server.stop();
   }

   @Test
   public void testApplicationPath() throws Exception
   {
      server.deployOldStyle(MyApp.class);
      Client client = ClientBuilder.newClient();
      String val = client.target(TestPortProvider.generateURL("/base/test"))
                         .request().get(String.class);
      Assert.assertEquals("hello world", val);
      client.close();
   }

   @Test
   public void testApplicationContext() throws Exception
   {
      server.deployOldStyle(MyApp.class, "/root");
      Client client = ClientBuilder.newClient();
      String val = client.target(TestPortProvider.generateURL("/root/test"))
                         .request().get(String.class);
      Assert.assertEquals("hello world", val);
      client.close();
   }

   @Test
   public void testDeploymentInfo() throws Exception
   {
      DeploymentInfo di = server.undertowDeployment(MyApp.class);
      di.setContextPath("/di");
      di.setDeploymentName("DI");
      server.deploy(di);
      Client client = ClientBuilder.newClient();
      String val = client.target(TestPortProvider.generateURL("/di/base/test"))
                         .request().get(String.class);
      Assert.assertEquals("hello world", val);
      client.close();
   }
}

]]></programlisting>
        </para>
    </section>
    <section>
        <title>Sun JDK HTTP Server</title>
        <para>
            The Sun JDK comes with a simple HTTP server implementation (com.sun.net.httpserver.HttpServer) which you
            can run RESTEasy on top of.
        </para>
    <programlisting> <![CDATA[
      HttpServer httpServer = HttpServer.create(new InetSocketAddress(port), 10);
      contextBuilder = new HttpContextBuilder();
      contextBuilder.getDeployment().getActualResourceClasses().add(SimpleResource.class);
      HttpContext context = contextBuilder.bind(httpServer);
      context.getAttributes().put("some.config.info", "42");
      httpServer.start();

      contextBuilder.cleanup();
      httpServer.stop(0);
    ]]></programlisting>
    <para>
        Create your HttpServer the way you want then use the org.jboss.resteasy.plugins.server.sun.http.HttpContextBuilder to initialize Resteasy
        and bind it to an HttpContext.  The HttpContext attributes are available by injecting in a org.jboss.resteasy.spi.ResteasyConfiguration
        interface using @Context within your provider and resource classes.

    </para>
    <para>Maven project you must include is:</para>
<programlisting> <![CDATA[
  <dependency>
      <groupId>org.jboss.resteasy</groupId>
      <artifactId>resteasy-jdk-http</artifactId>
      <version>4.7.9.Final</version>
  </dependency>
]]></programlisting>

   
    </section>

    <section>
        <title>Netty</title>
        <para>
            RESTEasy has integration with the popular Netty project as well..
        </para>
    <programlisting> <![CDATA[
   public static void start(ResteasyDeployment deployment) throws Exception
   {
      netty = new NettyJaxrsServer();
      netty.setDeployment(deployment);
      netty.setPort(TestPortProvider.getPort());
      netty.setRootResourcePath("");
      netty.setSecurityDomain(null);
      netty.start();
   }
    ]]></programlisting>

    <para>Maven project you must include is:</para>
<programlisting> <![CDATA[
  <dependency>
      <groupId>org.jboss.resteasy</groupId>
      <artifactId>resteasy-netty4</artifactId>
      <version>4.7.9.Final</version>
  </dependency>
]]></programlisting>

    </section>
    <section>
        <title>Reactor-Netty</title>
        <para>
            RESTEasy integrates with the reactor-netty project. This
            server adapter was created to pair with our reactor-netty
            based JAX-RS client integration. Ultimately, if using
            reactor-netty for both the server and server-contained
            clients you will be able to do things like share the same
            event loop for both server and client calls.
        </para>
    <programlisting> <![CDATA[
   public static void start(ResteasyDeployment deployment) throws Exception
   {
      ReactorNettyJaxrsServer server =  new ReactorNettyJaxrsServer();
      server.setDeployment(new ResteasyDeploymentImpl());
      server.setDeployment(deployment);
      server.setPort(TestPortProvider.getPort());
      server.setRootResourcePath("");
      server.setSecurityDomain(null);
      server.start();
   }
    ]]></programlisting>

    <para>Maven project you must include is:</para>
<programlisting> <![CDATA[
  <dependency>
      <groupId>org.jboss.resteasy</groupId>
      <artifactId>resteasy-reactor-netty</artifactId>
      <version>4.7.9.Final</version>
  </dependency>
]]></programlisting>

    </section>
  <section>
    <title>Vert.x</title>
    <para>
      RESTEasy has integration with the popular Vert.x project as well..
    </para>
    <programlisting> <![CDATA[
   public static void start(VertxResteasyDeployment deployment) throws Exception
   {
      VertxJaxrsServer server = new VertxJaxrsServer();
      server.setDeployment(deployment);
      server.setPort(TestPortProvider.getPort());
      server.setRootResourcePath("");
      server.setSecurityDomain(null);
      server.start();
   }
    ]]></programlisting>

    <para>Maven project you must include is:</para>
    <programlisting> <![CDATA[
  <dependency>
      <groupId>org.jboss.resteasy</groupId>
      <artifactId>resteasy-vertx</artifactId>
      <version>4.7.9.Final</version>
  </dependency>
    ]]></programlisting>

    <para>The server will bootstrap its own Vert.x instance and Http server.</para>

    <para>When a resource is called, it is done with the Vert.x Event Loop thread, keep in mind to
    not block this thread and respect the Vert.x programming model, see the related Vert.x <ulink url="http://vertx.io/docs/vertx-core/java/#_don_t_block_me">manual page</ulink>.</para>

    <para>Vert.x extends the RESTEasy registry to  provide a new binding scope that creates resources per Event Loop:</para>
    <programlisting> <![CDATA[
  VertxResteasyDeployment deployment = new VertxResteasyDeployment();
  // Create an instance of resource per Event Loop
  deployment.getRegistry().addPerInstanceResource(Resource.class);
    ]]></programlisting>

    <para>The per instance binding scope caches the same resource instance for each event loop providing the same
    concurrency model than a verticle deployed multiple times.</para>

    <para>Vert.x can also embed a RESTEasy deployment, making easy to use Jax-RS annotated controller in Vert.x applications: </para>
    <programlisting> <![CDATA[
  Vertx vertx = Vertx.vertx();
  HttpServer server = vertx.createHttpServer();

  // Set an handler calling Resteasy
  server.requestHandler(new VertxRequestHandler(vertx, deployment));

  // Start the server
  server.listen(8080, "localhost");
    ]]></programlisting>

    <para>Vert.x objects can be injected in annotated resources:</para>
    <programlisting> <![CDATA[
  @GET
  @Path("/somepath")
  @Produces("text/plain")
  public String context(
      @Context io.vertx.core.Context context,
      @Context io.vertx.core.Vertx vertx,
      @Context io.vertx.core.http.HttpServerRequest req,
      @Context io.vertx.core.http.HttpServerResponse resp) {
    return "the-response";
  }
    ]]></programlisting>

  </section>
   <section>
   <title>EmbeddedJaxrsServer</title>
   <para>
       <classname>EmbeddedJaxrsServer</classname> is an interface provided to enable each embedded container
       wrapper class to configurate, start and stop its container in a standard fashion.
       Each of <classname>UndertowJaxrsServer</classname>, <classname>SunHttpJaxrsServer</classname>,
       <classname>NettyJaxrsServer</classname>, and <classname>VertxJaxrsServer</classname> implements
       <classname>EmbeddedJaxrsServer</classname>.
   </para>
   <programlisting> <![CDATA[
      public interface EmbeddedJaxrsServer<T> {
         T deploy();
         T start();
         void stop();
         ResteasyDeployment getDeployment();
         T setDeployment(ResteasyDeployment deployment);
         T setPort(int port);
         T setHostname(String hostname);
         T setRootResourcePath(String rootResourcePath);
         T setSecurityDomain(SecurityDomain sc);
      }
    ]]></programlisting>
   </section>
</chapter>
