<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
<chapter id="deployment-descriptors">
  <title>TorqueBox Deployment Descriptors</title>

  <para>TorqueBox applications contain one central but optional internal deployment
  descriptor. A deployment descriptor is simply a configuration file that
  affects how your components are woven together at deployment time. The
  internal deployment descriptor used by TorqueBox can be either a YAML text
  file (known as <filename>torquebox.yml</filename>) or a Ruby file (known as
  <filename>torquebox.rb</filename>).</para>

  <para>The deployment descriptor may be placed inside your application so
  that it is entirely self-contained. Alternatively, an additional (YAML only)
  external descriptor may be used outside of your application, overriding portions of
  the descriptor contained within the application.</para>

  <para>Each subsystem within TorqueBox may contribute one or more
  configurable sections to the descriptor. For more information on the various
  subsystem descriptor sections, please see: <xref linkend="web" />,
  <xref linkend="messaging" />, <xref linkend="stomp" />, 
  <xref linkend="scheduled-jobs" />, <xref linkend="services" />, 
  <xref linkend="resource-injection" />, <xref linkend="authentication" />, and <xref
  linkend="pooling" />.</para>

  <section id="external-and-internal-descriptors">
    <title>External and Internal descriptors</title>

    <para>Deployment descriptors may be "external", residing outside the
    application, or "internal", residing within it. The descriptors come in
    two flavors: YAML-formatted text files and Ruby text files using the
    TorqueBox configuration DSL. Internal descriptors may use either form, but
    external descriptors are required to be YAML files.</para>

    <para>An <emphasis>external</emphasis> descriptor references an
    application somewhere on your filesystem. To deploy the application, the
    descriptor is placed in the
    <filename>$TORQUEBOX_HOME/jboss/standalone/deployments/</filename>
    directory of the TorqueBox server. The external descriptor's name should
    have a suffix of <filename>-knob.yml</filename> .</para>

    <para>An <emphasis>internal</emphasis> descriptor should be named
    <filename>torquebox.yml</filename> or <filename>torquebox.rb</filename>
    and reside inside the application's <filename>config/</filename>
    directory, if present, otherwise at the root. Internal descriptors allow
    you to override the TorqueBox defaults but only for a single app. As such,
    they are not required. Values in the external descriptor override those in
    the internal descriptor which, in turn, override the TorqueBox defaults.
    The YAML syntax used in the external descriptor is identical to the syntax
    available to the internal descriptor.</para>
  </section>

  <section id="contents-of-deployment-descriptors">
    <title>Contents of a descriptor</title>

    <para>There are two syntaxes available for use in an internal descriptor:
    YAML and a Ruby DSL. For the configuration specifics for each subystem,
    see: <xref linkend="web" />,
    <xref linkend="messaging" />, <xref linkend="stomp" />, 
    <xref linkend="scheduled-jobs" />, <xref linkend="services" />, 
    <xref linkend="resource-injection" />, <xref linkend="authentication" />, and <xref
    linkend="pooling" />.</para>

    <section id="yaml-descriptor-layout">
      <title>YAML syntax layout</title>

      <para>The YAML descriptor has several sections, grouped by subsystem,
      represented as top-level keys in a YAML associative array.</para>

    </section>

    <section id="ruby-descriptor-layout">
      <title>Ruby DSL syntax layout</title>

      <para>The DSL does not follow the strict sections of the YAML syntax,
      but the corresponding DSL methods can be grouped and described in the
      same manner.</para>

      <para>To use the DSL, you nest your configuration inside the block
      passed to <methodname>TorqueBox.configure</methodname> inside
      <filename>torquebox.rb</filename>:<informalexample>
          <para><programlisting>TorqueBox.configure do
  # DSL calls go here
end</programlisting></para>
        </informalexample></para>

      <para>The <methodname>TorqueBox.configure</methodname> method and the
      DSL methods that take a block can be given a block with or without an
      argument. If given a block argument, the block will receive a proxy
      object that must be used to call the DSL methods. Without an argument,
      the block will use <methodname>instance_eval</methodname> to evaluate
      the DSL calls, which will cause issues if you refer to any variables
      that aren't defined within the scope of the block. Most of the
      documentation examples use the <methodname>instance_eval</methodname>
      (no argument) block syntax.</para>

      <para>Using no-argument blocks:<informalexample>
          <para><programlisting>TorqueBox.configure do
  web do
    context "/"
  end
end</programlisting></para>
        </informalexample> Using argument blocks:<informalexample>
          <para><programlisting>TorqueBox.configure do |cfg|
  cfg.web do |web|
    web.context "/"
  end
end</programlisting></para>
        </informalexample> You can also mix &amp; match:<informalexample>
          <para><programlisting>TorqueBox.configure do
  web do |web|
    web.context "/"
  end

  ruby do
    version "1.9"
  end
end</programlisting></para>
        </informalexample></para>

      <para>Some DSL methods can also take their options as a hash instead of
      method calls nested in a block: <informalexample>
          <para><programlisting>TorqueBox.configure do
  web :context =&gt; "/", :host =&gt; "example.com"

  # is equivalent to:

  web do
    context "/"
    host "example.com"
  end
end</programlisting></para>
        </informalexample></para>
    </section>

    <section id="general-application-config-in-descriptor">
      <title>General Application Configuration</title>

      <formalpara>
        <title>Location</title>

        <para>The application section describes the location for the app
        itself. Under traditional (mongrel, lighttpd) deployments, this
        information is picked up through the current working directory. Since
        the TorqueBox Server runs from a different location, the current
        working directory has no meaning.</para>
      </formalpara>

      <table>
        <title>application</title>

        <tgroup cols="4">
          <colspec align="left" />

          <thead>
            <row>
              <entry>YAML Key</entry>

              <entry>DSL Method</entry>

              <entry>Description</entry>

              <entry>Default</entry>
            </row>
          </thead>

          <tbody>
            <row>
              <entry><varname>root</varname></entry>

              <entry><emphasis>none</emphasis></entry>

              <entry>Indicates the location of your application. It may refer
              to either an "exploded" application (a directory) or the path to
              a zipped archive. It is required for external descriptors and
              ignored in an internal descriptor. Rails apps will have this
              value set as ENV['RAILS_ROOT'], and Rack apps will have this
              value set to both the RACK_ROOT constant and
              ENV['RACK_ROOT'].</entry>

              <entry><emphasis>none</emphasis></entry>
            </row>
          </tbody>
        </tgroup>
      </table>

      <para>For example, in YAML: <informalexample>
          <para><programlisting>application:
  root: /path/to/myapp</programlisting></para>
        </informalexample></para>
    </section>

    <section id="ruby-runtime-config-in-descriptor">
      <title>Ruby runtime configuration</title>

      <para>TorqueBox exposes several of the JRuby runtime options: the ruby
      compatibility version, the JIT compile mode, and the debug setting.
      There's also a setting to enable interactive tty for the JRuby runtime
      for use with the Ruby debugger. All of these options are configured in
      the ruby: section of a deployment descriptor.</para>

      <para>Note that these settings are per application, allowing you to run
      1.8 and 1.9 applications in the same TorqueBox, or have one JIT'ed and
      another not.</para>

      <para>In a YAML configuration, the ruby settings are grouped under the
      <varname>ruby</varname> key. For the DSL, they are grouped within the
      <varname>ruby</varname> block.</para>

      <table>
        <title>ruby</title>

        <tgroup cols="3">
          <colspec align="left" />

          <thead>
            <row>
              <entry>YAML Key/DSL Method</entry>

              <entry>Description</entry>

              <entry>Default</entry>
            </row>
          </thead>

          <tbody>
            <row>
              <entry><varname>version</varname></entry>

              <entry>The ruby compatibility version for JRuby. Options are:
              <itemizedlist>
                  <listitem>
                    <para>1.8 - provides 1.8.7 compatibility</para>
                  </listitem>

                  <listitem>
                    <para>1.9 - provides 1.9.2 compatibility</para>
                  </listitem>
                </itemizedlist></entry>

              <entry>1.8</entry>
            </row>

            <row>
              <entry><varname>compile_mode</varname></entry>

              <entry>The JIT compile mode for JRuby. Options are:
              <itemizedlist>
                  <listitem>
                    <para>jit - Tells JRuby to use JIT on code where it
                    determines there will be a speed improvement</para>
                  </listitem>

                  <listitem>
                    <para>force - Tells JRuby to use JIT on all code</para>
                  </listitem>

                  <listitem>
                    <para>off - Turns off JIT completely</para>
                  </listitem>
                </itemizedlist></entry>

              <entry><parameter>jit</parameter></entry>
            </row>

            <row>
              <entry><varname>debug</varname></entry>

              <entry>A value of <emphasis>true</emphasis> enables JRuby's
              debug logging.</entry>

              <entry><parameter>false</parameter></entry>
            </row>

            <row>
              <entry><varname>interactive</varname></entry>

              <entry>A value of <emphasis>true</emphasis> sets up the
              stdin/stdout/stderr of the JRuby runtime for interactive use
              instead of being redirected to the logging subsystem. Enable
              this when using the Ruby debugger or the pry gem.</entry>

              <entry><parameter>false</parameter></entry>
            </row>

            <row>
              <entry><varname>profile_api</varname></entry>
              <entry>A value of <emphasis>true</emphasis> enables JRuby's 
              profiler instrumentation, which allows you to obtain performance 
              information on a given block of ruby code.

              <para>For more information, check out 
              <ulink url="http://danlucraft.com/blog/2011/03/built-in-profiler-in-jruby-1.6/">How to Use the New JRuby Profiler</ulink>
              </para>
              </entry>

              <entry><parameter>false</parameter></entry> 
            </row>

          </tbody>
        </tgroup>
      </table>

      <para>For example, in YAML: <informalexample>
          <para><programlisting>ruby:
  version: 1.9
  compile_mode: off
  debug: false
  interactive: true
  profile_api: true</programlisting></para>
        </informalexample> And via the DSL: <informalexample>
          <para><programlisting>TorqueBox.configure do
  ruby do
    version "1.9"
    compile_mode "off"
    debug false
    interactive true
    profile_api true
  end
end</programlisting></para>
        </informalexample></para>
    </section>

    <section id="environment-variables-config-in-descriptor">
      <title>Environment variables</title>

      <para>Each application may have its own unique set of environment
      variables, no matter how many different apps are deployed under a single
      TorqueBox instance. Variables from internal and external descriptors are
      merged, with the external variables overriding any internal matching
      keys.</para>

      <para>In a YAML configuration, the environment settings are grouped
      under the <varname>environment</varname> key. For the DSL, they are
      grouped within the <varname>environment</varname> block.</para>

      <para>For example, in YAML: <informalexample>
          <para><programlisting>environment:
  MAIL_HOST: mail.yourhost.com
  REPLY_TO: you@yourhost.com</programlisting></para>
        </informalexample> And via the DSL: <informalexample>
          <para><programlisting>TorqueBox.configure do 
  environment do
    MAIL_HOST 'mail.yourhost.com'
    REPLY_TO 'you@yourhost.com'
  end
end</programlisting></para>
        </informalexample></para>

      <para>Any variable set in the environment section is accessible from
      within the application using the ENV hash, e.g.
      ENV['MAIL_HOST']=='mail.yourhost.com'</para>

      <section id="application-environment">
        <title>Application environment</title>

        <para>To set the environment for the application, set either RACK_ENV
        or RAILS_ENV as an environment variable. They are equivalent, and will
        both work for a Rack or Rails application. If the application
        environment is not set, it will default to 'development'. Rails apps
        will have this value set as ENV['RAILS_ENV'] (which Rails itself will
        assign to Rails.env), and Rack apps will have this value set to both
        the RACK_ENV constant and ENV['RACK_ENV'].</para>

        <para>For example, in YAML: <informalexample>
            <para><programlisting>environment:
  RAILS_ENV: production</programlisting></para>

          </informalexample> And via the DSL: <informalexample>
            <para><programlisting>TorqueBox.configure do 
  environment do
    RAILS_ENV 'production'
  end
end</programlisting></para>
          </informalexample></para>
      </section>
    </section>
  </section>

  <section id="java-deployment-descriptors">
    <title>Java Deployment Descriptors</title>

    <para>In addition to Ruby, Rails and TorqueBox-specific descriptors, your
    application may also include any traditional JavaEE or JBoss-specific
    descriptors within its <filename>config/</filename> directory.</para>

    <section id="webinf-web-xml">
      <title>WEB-INF/web.xml</title>

      <para>A JavaEE <filename>web.xml</filename> deployment descriptor may be
      included in your application's <filename>WEB-INF/</filename> directory.
      Additional Java Servlets, Filters or other configuration may be
      performed within this file. Its contents will be mixed with other
      information when your application is deployed. If desired, your
      <filename>web.xml</filename> may reference the components that TorqueBox
      implicitly adds.</para>

      <formalpara>
        <title>Rack Filter</title>

        <para>TorqueBox provides a <productname>Java Servlet</productname>
        <classname>Filter</classname> named
        <parameter>torquebox.rack</parameter>. This filter is responsible for
        delegating requests to Rack-based applications.</para>
      </formalpara>

      <formalpara>
        <title>Static Resource Servlet</title>

        <para>In order to serve files from the <filename>public/</filename>
        directory of your application, TorqueBox installs a
        <classname>Servlet</classname> named
        <parameter>torquebox.static</parameter>.</para>
      </formalpara>
    </section>
  </section>
</chapter>
