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

== Quick Start

These instructions should help you get Apache Karaf up and running in 5 to 15 minutes.

=== Prerequisites

Karaf requires a Java SE 7 or Java SE 8 environment to run. Refer to http://www.oracle.com/technetwork/java/javase/ for details on how to download and install Java SE 1.7 or greater.

* Open a Web browser and access the following URL: http://karaf.apache.org/index/community/download.html
* Download the binary distribution that matches your system (zip for windows, tar.gz for unixes)
* Extract the archive to a new folder on your hard drive; for example in c:\karaf - from now on this directory will be referenced as <KARAF_HOME>.

=== Start the server

Open a command line console and change the directory to <KARAF_HOME>.

To start the server, run the following command in Windows:

----
bin\karaf.bat
----

respectively on Unix:

----
bin/karaf
----

You should see the following information on the command line console:

----
        __ __                  ____
       / //_/____ __________ _/ __/
      / ,<  / __ `/ ___/ __ `/ /_
     / /| |/ /_/ / /  / /_/ / __/
    /_/ |_|\__,_/_/   \__,_/_/

  Apache Karaf (4.0.0)

Hit '<tab>' for a list of available commands
and '[cmd] --help' for help on a specific command.
Hit '<ctrl-d>' or type 'system:shutdown' or 'logout' to shutdown Karaf.

karaf@root()>

----

=== Shell console basics

You can now run your first command.  Simply type the `<tab>` key in the console.

----
karaf@root()> Display all 294 possibilities? (y or n)
...
shell:logout                        shell:more                          shell:new                           shell:printf                        shell:sleep                         shell:sort                          shell:source
shell:stack-traces-print            shell:tac                           shell:tail                          shell:threads                       shell:watch                         shell:wc                            shell:while
shutdown                            sleep                               sort                                source                              ssh                                 ssh                                 ssh-host-change
ssh-port-change                     ssh:ssh                             stack-traces-print                  start                               start-level                         status                              stop
su                                  sudo                                system                              system:framework                    system:name                         system:property                     system:shutdown
system:start-level                  system:version                      tac                                 tail                                threads                             tree-show                           uninstall
update                              user-add                            user-delete                         user-list                           version                             version-list                        wait
watch                               wc                                  while
----

You can then grab more specific help for a given command using the `--help` option for this command:

----
karaf@root()> bundle:list --help
DESCRIPTION
        bundle:list

        Lists all installed bundles.

SYNTAX
        bundle:list [options] [ids]

ARGUMENTS
        ids
                The list of bundle (identified by IDs or name or name/version) separated by whitespaces

OPTIONS
        -t
                Specifies the bundle threshold; bundles with a start-level less than this value will not get printed out.
        --no-format
                Disable table rendered output
        -s
                Shows the symbolic name
        -l
                Show the locations
        --no-ellipsis

        --help
                Display this help message
        -u
                Shows the update locations
        --context, -c
                Use the given bundle context
                (defaults to 0)
        -r
                Shows the bundle revisions
----

Note that the console supports tab completion so if you start typing a command it will show all possible completions and also auto complete if there is only one completion.

=== Deploy a sample application

While you will learn in the Karaf user's guide how to fully use and leverage Apache Karaf, let's install a sample http://camel.apache.org[Apache Camel] application for now:

In the console, run the following commands:

----
karaf@root()> feature:repo-add camel 2.15.2
Adding feature url mvn:org.apache.camel.karaf/apache-camel/2.15.2/xml/features
karaf@root()> feature:install camel-spring
karaf@root()> bundle:install -s mvn:org.apache.camel/camel-example-osgi/2.15.2
Bundle ID: 82
----

The example installed is using Camel to start a timer every 2 seconds and output a message in the log.
The previous commands download the Camel features descriptor and install the example feature.

You can display the log in the shell:

----
karaf@root()> log:display
...
2015-06-30 13:39:44,731 | INFO  |  timer://myTimer | ExampleRouter                    | 53 - org.apache.camel.camel-core - 2.15.2 | Exchange[ExchangePattern: InOnly, BodyType: String, Body: SpringDSL set body:  Tue Jun 30 13:39:44 CEST 2015]
2015-06-30 13:39:46,730 | INFO  |  timer://myTimer | MyTransform                      | 82 - camel-example-osgi - 2.15.2 | >>>> SpringDSL set body:  Tue Jun 30 13:39:46 CEST 2015
2015-06-30 13:39:46,731 | INFO  |  timer://myTimer | ExampleRouter                    | 53 - org.apache.camel.camel-core - 2.15.2 | Exchange[ExchangePattern: InOnly, BodyType: String, Body: SpringDSL set body:  Tue Jun 30 13:39:46 CEST 2015]
2015-06-30 13:39:48,730 | INFO  |  timer://myTimer | MyTransform                      | 82 - camel-example-osgi - 2.15.2 | >>>> SpringDSL set body:  Tue Jun 30 13:39:48 CEST 2015
2015-06-30 13:39:48,730 | INFO  |  timer://myTimer | ExampleRouter                    | 53 - org.apache.camel.camel-core - 2.15.2 | Exchange[ExchangePattern: InOnly, BodyType: String, Body: SpringDSL set body:  Tue Jun 30 13:39:48 CEST 2015]
----

=== Stopping and uninstalling the sample application

To stop and uninstall the demo, run the following command:

----
karaf@root()> bundle:stop camel-example-osgi
karaf@root()> bundle:uninstall camel-example-osgi
----

=== Stopping Karaf

To stop Karaf from the console, enter `^D` in the console:

----
^D
----

Alternatively, you can also run the following command:

----
karaf@root()> system:shutdown
----

halt is also an alias for system:shutdown:

----
karaf@root()> halt
----

=== Cleaning the Karaf state

Normally Karaf remembers the features and bundles you installed and started. To reset Karaf into a clean state, just delete the data directory when Karaf is not running.

=== Summary

This document shows how simple it is to get Apache Karaf up and running and install a simple Apache Camel application.
