//
// 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.
//

=== HTTP Balancer

Apache Karaf Cellar is able to expose servlets local to a node on the cluster.
It means that a client (browser) can use any node in the cluster, proxying the requests to the node actually
hosting the servlets.

==== Enable HTTP Balancer

To enable Cellar HTTP Balancer, you have to first install the `http` and `http-whiteboard` features:

----
karaf@root()> feature:install http
karaf@root()> feature:install http-whiteboard
----

Now, we install the `cellar-http-balancer` feature, actually providing the balancer:

----
karaf@root()> feature:install cellar-http-balancer
----

Of course, you can use Cellar to spread the installation of the `cellar-http-balancer` feature on all nodes in the
cluster group:

----
karaf@root()> cluster:feature-install default cellar-http-balancer
----

It's done: the Cellar HTTP Balancer is now enabled. It will expose proxy servlets on nodes.

==== Balancer in action

To illustrate Cellar HTTP Balancer in action, you need at least a cluster with two nodes.

On node1, we enable the Cellar HTTP Balancer:

----
karaf@node1()> feature:install http
karaf@node1()> feature:install http-whiteboard
karaf@node1()> feature:repo-add cellar 4.0.0
karaf@node1()> feature:install cellar
karaf@node1()> cluster:feature-install default cellar-http-balancer
----

Now, we install the webconsole on node1:

----
karaf@node1()> feature:install webconsole
----

We can see the "local" servlets provided by the webconsole feature using the `http:list` command:

----
karaf@node1()> http:list
ID  | Servlet          | Servlet-Name    | State       | Alias               | Url
------------------------------------------------------------------------------------------------------
101 | KarafOsgiManager | ServletModel-2  | Undeployed  | /system/console     | [/system/console/*]
103 | GogoPlugin       | ServletModel-7  | Deployed    | /gogo               | [/gogo/*]
102 | FeaturesPlugin   | ServletModel-6  | Deployed    | /features           | [/features/*]
101 | ResourceServlet  | /res            | Deployed    | /system/console/res | [/system/console/res/*]
101 | KarafOsgiManager | ServletModel-11 | Deployed    | /system/console     | [/system/console/*]
105 | InstancePlugin   | ServletModel-9  | Deployed    | /instance           | [/instance/*]
----

You can access to the webconsole using a browser on http://localhost:8181/system/console.

We can see that Cellar HTTP Balancer exposed the servlets to the cluster, using the `cluster:http-list` command:

----
karaf@node1()> cluster:http-list default
Alias               | Locations
-----------------------------------------------------------------
/system/console/res | http://172.17.42.1:8181/system/console/res
/gogo               | http://172.17.42.1:8181/gogo
/instance           | http://172.17.42.1:8181/instance
/system/console     | http://172.17.42.1:8181/system/console
/features           | http://172.17.42.1:8181/features
----

On another node (node2), we install `http`, `http-whiteboard` and `cellar` features:

----
karaf@node2()> feature:install http
karaf@node2()> feature:install http-whiteboard
karaf@node2()> feature:repo-add cellar 4.0.0
karaf@node2()> feature:install cellar
----

[NOTE]
====
If you run the nodes on a single machine, you have to provision `etc/org.ops4j.pax.web.cfg` configuration file
containing the `org.osgi.service.http.port property` with a port number different to 8181.
For this example, we use the following `etc/org.ops4j.pax.web.cfg` file:

----
org.osgi.service.http.port=8041
----
====

On node1, as we installed the `cellar-http-balancer` using `cluster:feature-install` command, it's automatically installed
when node2 joins the default cluster group.

We can see the HTTP endpoints available on the cluster using the `cluster:http-list` command:

----
karaf@node2()> cluster:http-list default
Alias               | Locations
-----------------------------------------------------------------
/system/console/res | http://172.17.42.1:8181/system/console/res
/gogo               | http://172.17.42.1:8181/gogo
/instance           | http://172.17.42.1:8181/instance
/system/console     | http://172.17.42.1:8181/system/console
/features           | http://172.17.42.1:8181/features
----

If we take a look on the HTTP endpoints locally available on node2 (using `http:list` command), we can see the proxies
created by Cellar HTTP Balancer:

----
karaf@node2()> http:list
ID  | Servlet                    | Servlet-Name   | State       | Alias               | Url
---------------------------------------------------------------------------------------------------------------
100 | CellarBalancerProxyServlet | ServletModel-3 | Deployed    | /gogo               | [/gogo/*]
100 | CellarBalancerProxyServlet | ServletModel-2 | Deployed    | /system/console/res | [/system/console/res/*]
100 | CellarBalancerProxyServlet | ServletModel-6 | Deployed    | /features           | [/features/*]
100 | CellarBalancerProxyServlet | ServletModel-5 | Deployed    | /system/console     | [/system/console/*]
100 | CellarBalancerProxyServlet | ServletModel-4 | Deployed    | /instance           | [/instance/*]
----

You can use a browser on http://localhost:8041/system/console: you will actually use the webconsole from node1, as
Cellar HTTP Balancer proxies from node2 to node1.

Cellar HTTP Balancer randomly chooses one endpoint providing the HTTP endpoint.
