//
//  ========================================================================
//  Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others.
//  ========================================================================
//  All rights reserved. This program and the accompanying materials
//  are made available under the terms of the Eclipse Public License v1.0
//  and Apache License v2.0 which accompanies this distribution.
//
//      The Eclipse Public License is available at
//      http://www.eclipse.org/legal/epl-v10.html
//
//      The Apache License v2.0 is available at
//      http://www.opensource.org/licenses/apache2.0.php
//
//  You may elect to redistribute this code under either of these licenses.
//  ========================================================================
//

[[overlay-deployer]]
=== Overlay WebApp Deployer

____
[NOTE]
This feature was reintroduced in Jetty 9.0.4
____

The Jetty Overlay Deployer allows multiple WAR files to be overlaid so that a web application can be customized, configured, and deployed without unpacking, modifying and repacking the WAR file.
This has the following benefits:

* WAR files can be kept immutable, even signed, so that it is clear which version is deployed.
* All modifications made to customize/configure the web application are separate WARs, and thus are easily identifiable for review and migration to new versions.
* A parameterized template overlay can be created that contains common customizations and configuration that apply to many instances of the web application (for example, for multi-tenant deployment).
* Because the layered deployment clearly identifies the common and instance specific components, Jetty is able to share classloaders and static resource caches for the template, greatly reducing the memory footprint of multiple instances.

This tutorial describes how to configure Jetty to use the Overlay Deployer, and how to deploy multiple instances of a web application using the JTrac application in the example.

[[overlay-overview]]
==== Overview

Customizing, configuring and deploying a web application bundled as a WAR file frequently includes some or all of these steps:

* Editing the `WEB-INF/web.xml` file to set init parameters, add filters/servlets or to configure JNDI resources.
* Editing other application specific configuration files under `WEB-INF/`.
* Editing container specific configuration files under `WEB-INF/` (for example, `jetty-web.xml` or `jboss-web.xml`).
* Adding/modifying static content such as images and CSS to create a style or themes for the web application.
* Adding Jars to the container classpath for Datasource and other resources.
* Modifying the container configuration to provide JNDI resources.

The result is that the customizations and configurations blend into both the container and the WAR file.
If either the container or the base WAR file is upgraded to a new version, it can be a very difficult and error prone task to identify all the changes that have been made and to reapply them to a new version.

[[overlay-overlays]]
==== Overlays

To solve the problems highlighted above, Jetty introduced WAR overlays (a concept borrowed from the Maven WAR plugin).
An overlay is basically just another WAR file, whose contents merge on top of the original WAR so that filed can be added or replaced.
Jetty overlays also allow fragments of `web.xml` to be mixed in, which means the configuration can be modified without replacing it.

[[overlay-jtrac]]
==== JTrac Overlay Example

The JTrac issue tracking web application is a good example of a typical web application, as it uses the usual suspects of libs: spring, hibernate, dom4j, commons-*, wicket, etc.
The files for this demonstration are available in overlays-demo.tar.gz.
The demonstration can be expanded on top of the Jetty distribution; this tutorial expands it to /tmp and installs the components step-by-step:

[source, screen, subs="{sub-order}"]
----
$ cd /tmp
$ wget http://webtide.com/wp-content/uploads/2011/05/overlays-demo.tar.gz
$ tar xfvz overlays-demo.tar.gz
$ export OVERLAYS=/tmp/overlays
----

[[overlay-configure]]
==== Configuring Jetty for Overlays

Overlays support is included in jetty distributions from 7.4.1-SNAPSHOT onwards, which can be downloaded from oss.sonatype.org or Maven Central and unpack into a directory.
The `start.ini` file needs edited so that it includes the overlay option and configuration file.
The resulting file should look like:

[source, plain, subs="{sub-order}"]
----
OPTIONS=Server,jsp,jmx,resources,websocket,ext,overlay
etc/jetty.xml
etc/jetty-deploy.xml
etc/jetty-overlay.xml
----

The mechanics of this are in etc/jetty-deploy.xml, which installs the `OverlayedAppProvider` into the `DeploymentManager`.
Jetty can then be started normally:

[source, screen, subs="{sub-order}"]
----
$ java -jar start.jar
----

Jetty is now listening on port 8080, but with no webapp deployed.

____
[IMPORTANT]
You should conduct the rest of the tutorial in another window with the JETTY_HOME environmental variable set to the Jetty distribution directory.
____

[[overlay-install]]
==== Installing the WebApp

The WAR file for this demo can be downloaded and deployed the using the following commands, which downloads and extracts the WAR file to the $JETTY_HOME/overlays/webapps directory.

[source, screen, subs="{sub-order}"]
----
$ cd /tmp
$ wget -O jtrac.zip http://sourceforge.net/projects/j-trac/files/jtrac/2.1.0/jtrac-2.1.0.zip/download
$ jar xfv jtrac.zip jtrac/jtrac.war
$ mv jtrac/jtrac.war $JETTY_HOME/overlays/webapps
----

When these commands (or equivalent) have been executed, a message that the `OverlayedAppProvider` has extracted and loaded the WAR file will be displayed in the Jetty server window:

[source, plain, subs="{sub-order}"]
----
2011-05-06 10:31:54.678:INFO:OverlayedAppProvider:Extract jar:file:/tmp/jetty-distribution-7.4.1-SNAPSHOT/overlays/webapps/jtrac-2.1.0.war!/ to /tmp/jtrac-2.1.0_236811420856825222.extract
2011-05-06 10:31:55.235:INFO:OverlayedAppProvider:loaded jtrac-2.1.0@1304641914666
----

Unlike the normal webapps dir, loading a WAR file from the overlays/webapp dir does not deploy the web application, it simply makes it available to use as the basis for templates and overlays.

==== Installing a Template Overlay

A template overlay is a WAR structured directory/archive that contains the files that have been added or modified to customize/configure the web application for all instances planned for deployment.

The demo template can be installed from the downloaded files with the command:

[source, screen, subs="{sub-order}"]
----
$ mv $OVERLAYS/jtracTemplate\=jtrac-2.1.0 $JETTY_HOME/overlays/templates/
----

In the Jetty server window, a message similar to this will be displayed confirmed that the template is loaded:

[source, plain, subs="{sub-order}"]
----
2011-05-06 11:00:08.716:INFO:OverlayedAppProvider:loaded jtracTemplate=jtrac-2.1.0@1304643608715
----

The contents of the loaded template are as follows:

[source, plain, subs="{sub-order}"]
----
templates/jtracTemplate=jtrac-2.1.0
|__ WEB-INF
    |__ classes
    |   |__ jtrac-init.properties
    |__ log4j.properties
    |__ overlay.xml
    |__ template.xml
    |__ web-overlay.xml
----

name of the template directory (or WAR)::
  Uses the ‘=’ character in jtracTemplate=jtrac-2.1.0 to separate the name of the template from the name of the WAR file in webapps that it applies to.
  If = is a problem, use -- instead.
WEB-INF/classes/jtrac-init.properties::
  Replaces the JTrac properties file with an empty file, as the properties it contains are configured elsewhere.
WEB-INF/log4j.properties::
  Configures the logging for all instances of the template.
WEB-INF/overlay.xml::
  A Jetty XML formatted IoC file that injects/configures the `ContextHandler` for each instance. \
  In this case it sets up the context path:

[source, xml, subs="{sub-order}"]
----
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure.dtd">
<Configure class="org.eclipse.jetty.webapp.WebAppContext">
  <Set name="contextPath">/</Set>
</Configure>
----

WEB-INF/template.xml::
  A Jetty XML formatted IoC file that injects/configures the resource cache and classloader that all instances of the template share.
  It runs only once per load of the template:

[source, xml, subs="{sub-order}"]
----
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure.dtd">
<Configure class="org.eclipse.jetty.overlays.TemplateContext">
  <Get name="resourceCache">
    <Set name="useFileMappedBuffer">true</Set>
    <Set name="maxCachedFileSize">10000000</Set>
    <Set name="maxCachedFiles">1000</Set>
    <Set name="maxCacheSize">64000000</Set>
  </Get>
</Configure>
----

WEB-INF/web-overlay.xml::
  A `web.xml` fragment that Jetty overlays on top of the `web.xml` from the base WAR file; it can set init parameters and add/modify filters and
  servlets.
  In this example it sets the application home and springs `webAppRootKey`:

[source, xml, subs="{sub-order}"]
----
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/j2ee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
    version="2.4">
  <context-param>
    <param-name>jtrac.home</param-name>
    <param-value>/tmp/jtrac-${overlay.instance.classifier}</param-value>
  </context-param>
  <context-param>
    <param-name>webAppRootKey</param-name>
    <param-value>jtrac-${overlay.instance.classifier}</param-value>
  </context-param>
  <filter>
</web-app>
----

Notice the parameterization of values such as `${overlays.instance.classifier}`, as this allows the configuration to be in the template, and not customized for each instance.

Without the Overlay Deployer, all of the above would still need to have configure , but rather than being in a single clear structure the configuration elements would have been either in the server's common directory, the server's `webdefaults.xml` (aka `server.xml`), or baked into the WAR file of each application instance using copied/modified files from the original.
The Overlay Deployer allows all these changes to be made in one structure; moreover it allows for the parameterization of some of the configuration, which facilitates easy multi-tenant deployment.

==== Installing an Instance Overlay

Now that the template is installed, one or more instance overlays can be implemented to deploy the actual web applications:

[source, screen, subs="{sub-order}"]
----
$ mv /tmp/overlays/instances/jtracTemplate\=blue $JETTY_HOME/overlays/instances/
$ mv /tmp/overlays/instances/jtracTemplate\=red $JETTY_HOME/overlays/instances/
$ mv /tmp/overlays/instances/jtracTemplate\=blue $JETTY_HOME/overlays/instances/
----

As each instance moves into place, the Jetty server window reacts and deploys the instance.
Within each instance, there is the structure:

[source, plain, subs="{sub-order}"]
----
instances/jtracTemplate=red/
|__ WEB-INF
|   |__ overlay.xml
|__ favicon.ico
|__ resources
    |__ jtrac.css
----

WEB-INF/overlay.xml::
  A Jetty XML format IoC file that injects/configures the context for the instance.
  In this case it sets up a virtual host for the instance:

[source, xml, subs="{sub-order}"]
----
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure.dtd">
<Configure class="org.eclipse.jetty.webapp.WebAppContext">
  <Set name="virtualHosts">
    <Array type="String">
      <Item>127.0.0.2</Item>
      <Item>red.myVirtualDomain.com</Item>
    </Array>
  </Set>
</Configure>
----

favicon.ico::
  Replaces the icon in the base WAR with one that has a theme for the instance; in this case red, blue, or green.
resources/jtrac.css::
  Replaces the style sheet from the base WAR with one that has a theme for the instance.

Deployed instances can be vied by pointing a browser at http://127.0.0.1:8080, http://127.0.0.2:8080 and http://127.0.0.3:8080.
The default username/password for JTrac is admin/admin.

[[overlay-tips]]
==== Things to Know and Notice

* Each instance has themes with images and style sheets from the instance overlay.
* Each instance is running with its own application directory (that is, /tmp/jtrac-red), set in templates web-overlay.xml.
* A virtual host set in the instance overlay.xml distinguishes the instances.
* All instances share static content from the base WAR and template.
Specifically there is a shared `ResourceCache` so only a single instance of each static content is loaded into memory.
* All instances share the classloader at the base WAR and template level, so that only a single instance of common classes is loaded into memory.
Classes with non shared statics can be configured to load in the instances classloader.
* Jetty hot deploys all overlays and tracks dependencies.
** If an XML changes in an instance, Jetty redeploys it.
** If an XML changes in a template, then Jetty redeploys all instances using it.
** If a WAR file changes, then Jetty redeploys all templates and all instances dependent on it.
* New versions can be easily deployed.
For example, when JTrac-2.2.0.war becomes available, it can be placed into `overlays/webapps` and then rename `jtracTemplate\=jtrac-2.1.0` to `jtracTemplate\=jtrac-2.2.0`.
* There is a fuller version of this demo in overlays-demo-jndi.tar.gz, that uses JNDI (needs `options=jndi`, annotations and `jetty-plus.xml` in `start.ini`) and shows how additional JARs can be added in the overlays.
