//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//

==== WebContainer (JSP/Servlet)

Apache Karaf can act a complete WebContainer, fully supporting JSP/Servlet specification.

Apache Karaf WebContainer supports both:

* WAB (WebApplication Bundles) which are OSGi native web applications
* WAR (WebApplication aRchives) which are non-OSGi web applications (the same as you can deploy in any web container like Apache Tomcat)

To enable the Apache Karaf WebContainer, you just have to install the `war` feature:

----
karaf@root()> feature:install war
----

[NOTE]
====
The installation of the `webconsole` feature automatically installs the `war` feature.
====

The `war` feature provides:

* an embedded web container (powered by Jetty), with its configuration
* a set of console commands
* a new war deployer

===== Configuration

The default port used by the WebContainer is 8181.

The WebContainer configuration is in the `etc/jetty.xml` configuration file.

The `etc/jetty.xml` is a standard Eclipse Jetty configuration file.

The default Apache Karaf WebContainer `etc/jetty.xml` contains:

----
<?xml version="1.0"?>
<!--
 Licensed to the Apache Software Foundation (ASF) under one
 or more contributor license agreements.  See the NOTICE file
 distributed with this work for additional information
 regarding copyright ownership.  The ASF licenses this file
 to you under the Apache License, Version 2.0 (the
 "License"); you may not use this file except in compliance
 with the License.  You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

 Unless required by applicable law or agreed to in writing,
 software distributed under the License is distributed on an
 "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 KIND, either express or implied.  See the License for the
 specific language governing permissions and limitations
 under the License.
-->
<!DOCTYPE Configure PUBLIC "-//Mort Bay Consulting//
DTD Configure//EN" "http://jetty.mortbay.org/configure.dtd">

<Configure class="org.eclipse.jetty.server.Server">

    <!-- =========================================================== -->
    <!-- Set connectors -->
    <!-- =========================================================== -->
    <!-- One of each type! -->
    <!-- =========================================================== -->

    <!-- Use this connector for many frequently idle connections and for
        threadless continuations. -->
    <Call name="addConnector">
        <Arg>
            <New class="org.eclipse.jetty.server.nio.SelectChannelConnector">
                <Set name="host">
                    <Property name="jetty.host" />
                </Set>
                <Set name="port">
                    <Property name="jetty.port" default="8181" />
                </Set>
                <Set name="maxIdleTime">300000</Set>
                <Set name="Acceptors">2</Set>
                <Set name="statsOn">false</Set>
                <Set name="confidentialPort">8443</Set>
                <Set name="lowResourcesConnections">20000</Set>
                <Set name="lowResourcesMaxIdleTime">5000</Set>
            </New>
        </Arg>
    </Call>

    <!-- =========================================================== -->
    <!-- Configure Authentication Realms -->
    <!-- Realms may be configured for the entire server here, or -->
    <!-- they can be configured for a specific web app in a context -->
    <!-- configuration (see $(jetty.home)/contexts/test.xml for an -->
    <!-- example). -->
    <!-- =========================================================== -->
    <Call name="addBean">
        <Arg>
            <New class="org.eclipse.jetty.plus.jaas.JAASLoginService">
                <Set name="name">karaf</Set>
                <Set name="loginModuleName">karaf</Set>
                <Set name="roleClassNames">
                    <Array type="java.lang.String">
                        <Item>org.apache.karaf.jaas.boot.principal.RolePrincipal
                        </Item>
                    </Array>
                </Set>
            </New>
        </Arg>
    </Call>
    <Call name="addBean">
        <Arg>
            <New class="org.eclipse.jetty.plus.jaas.JAASLoginService">
                <Set name="name">default</Set>
                <Set name="loginModuleName">karaf</Set>
                <Set name="roleClassNames">
                    <Array type="java.lang.String">
                        <Item>org.apache.karaf.jaas.boot.principal.RolePrincipal
                        </Item>
                    </Array>
                </Set>
            </New>
        </Arg>
    </Call>

</Configure>
----

The `SelectChannelConnector` defines the default connector of the WebContainer.

This connector defines the 8181 port number for the HTTP protocol (`port` property), and the 8443 port number for the
HTTPS protocol (`confidentialPort` property).

By default, Apache Karaf bind these ports on all network interfaces (`0.0.0.0`). You can config the `host` property
to bind on a specific network interface (with a given IP address).

The following resources give you details about advanced `etc/jetty.xml` configurations:

* http://wiki.eclipse.org/Jetty/Howto/Configure_Jetty
* http://wiki.eclipse.org/Jetty/Howto/Configure_SSL
* http://wiki.eclipse.org/Jetty/Reference/jetty.xml_syntax

===== Deploy

Apache Karaf WebContainer is able to deploy:

* pure OSGi WebApplication Bundle (WAB)
* "classical" standard WebApplication aRchive (WAR)

====== WAB (WebApplication Bundle)

A WAB is a standard WAR or JAR archive containing at least the following properties in the MANIFEST:

* `Bundle-ManifestVersion: 2` defines that the bundle follows the rules of R4 specification.
* `Bundle-SymbolicName` specifies a unique, non-localizable name for the bundle. This name should be based on the
 reverse domain name convention.
* `Web-ContextPath` specifies the location of the web application.

WAB can be deployed directly in Apache Karaf, for instance, by dropping the archive in the `deploy` folder, or using the
`bundle:install` command.

For instance, the Apache Karaf manual (documentation) is available as a WAB that you can deploy directly in a running instance:

----
karaf@root()> bundle:install -s mvn:org.apache.karaf/manual/4.0.0/war
----

====== WAR (WebApplication aRchive)

Apache Karaf allows you to deploy directly WAR files without repackaging as WAB.

Using the `webbundle` prefix and providing headers directly on the URL, Apache Karaf creates a WAB "on the fly".

For instance, you can deploy the Apache Tomcat sample non-OSGi "classical" WAR with the following command:

----
karaf@root()> bundle:install -s "webbundle:http://tomcat.apache.org/tomcat-7.0-doc/appdev/sample/sample.war?Bundle-SymbolicName=tomcat-sample&Web-ContextPath=/sample"
----

You can note the `webbundle` prefix, and the `Bundle-SymbolicName` and `Web-ContextPath` headers on the URL.

===== Commands

====== `http:list`

The `http:list` lists the available Servlets deployed in the WebContainer.

For instance, if you have installed the Apache Karaf WebConsole, you can see the WebConsole Servlets:

----
karaf@root()> http:list
ID  | Servlet          | Servlet-Name   | State       | Alias               | Url
-----------------------------------------------------------------------------------------------------
113 | ResourceServlet  | /res           | Deployed    | /system/console/res | [/system/console/res/*]
113 | KarafOsgiManager | ServletModel-2 | Undeployed  | /system/console     | [/system/console/*]
113 | KarafOsgiManager | ServletModel-5 | Deployed    | /system/console     | [/system/console/*]
----

The `ID` is the ID of the bundle which provides the servlet (`113` here).

The `State` is the current state of the Servlet (`Deployed` or `Undeployed`).

The `Url` is the URL where the Servlet is available.

====== `web:list`

The `web:list` command lists the WebApplication Bundles ("native" WAB or "wrapped WAR") deployed in the WebContainer.

For instance, if you installed the Apache Karaf manual WAR file as described previously, you can see it with `web:list`:

----
karaf@root()> web:list
ID  | State       | Web-State   | Level | Web-ContextPath | Name
---------------------------------------------------------------------------------------------------
111 | Active      | Deployed    | 80    | /karaf-doc      | Apache Karaf :: Manual (4.0.0)
----

====== `web:stop`

The `web:stop` command stops a web application in the WebContainer. The `web:stop` command expects a `id` argument
corresponding to the bundle ID (as displayed by the `web:list` command).

For instance, to stop the Apache Karaf manual web application:

----
karaf@root()> web:stop 111
----

====== `web:start`

The `web:start` command starts a web application in the WebContainer. The `web:start` command expects a `id` argument
corresponding to the bundle ID (as displayed by the `web:list` command).

For instance, to start the Apache Karaf manual web application:

----
karaf@root()> web:start 111
----

===== JMX HttpMBean

On the JMX layer, you have a MBean dedicated to the manipulation of the Servlets: the HttpMBean.

The ObjectName to use is `org.apache.karaf:type=http,name=*`.

====== Attributes

The `Servlets` attribute provides a tabular data providing the list of deployed Servlets including:

* `Alias` is the Servlet URL alias.
* `Bundle-ID` is the ID of the bundle which provides this Servlet.
* `Servlet` is the class name of the Servlet.
* `State` is the current Servlet state (`Deployed` or `Undeployed`).
* `URL` is the URL of the Servlet (the Servlet context path).

===== JMX WebMBean

On the JMX layer, you have a MBean dedicated to the manipulation of the Web Applications: the WebMBean.

The ObjectName to use is `org.apache.karaf:type=web,name=*`.

====== Attributes

The `WebBundles` attribute provides a tabular data providing the list of deployed Web Applications including:

* `ID` is the ID of the bundle providing the Web Application.
* `Level` is the bundle start level.
* `Name` is the bundle symbolic name providing the Web Application.
* `State` is the current state of the bundle.
* `Web-ContextPath` is the context path of the Web Application.
* `Web-State` is the current status of the Web Application (`Deployed` or `Undeployed`).

====== Operations

* `start(id)` starts the web context of the bundle with `id`.
* `start(list)` starts the web context of the bundles with ID in the provided `list`.
* `stop(id)` stops the web context of the bundle with `id`.
* `stop(list)` stops the web context of the bundles with ID in the provided `list`.

