[[running_Q2]]
== Running Q2

Running Q2 is as simple as calling +java -jar jpos.jar+, provided 
the jPOS dependencies are available in the +lib+ directory.

The reason why this works without setting a specific CLASSPATH is because
we have configured the build system to produce a suitable MANIFEST.MF
that contains the following relevant parts:

[source,xml]
-----
...
...
Main-Class: org.jpos.q2.Q2
Class-Path: lib/jdom-1.1.3.jar lib/jdbm-1.0.jar lib/je-4.1.10.jar lib/
 commons-cli-1.2.jar lib/jline-1.0.jar lib/bsh-2.0b5.jar lib/javatuple
  s-1.2.jar lib/xercesImpl-2.10.0.jar lib/org.osgi.core-4.3.1.jar lib/x
   ml-apis-1.4.01.jar
...
...
-----

[TIP]
=====
You can of course use the more convenient +bin/q2+ script (or +bin\q2.bat+ in Windows), 
but you don't have to worry about setting up a classpath if the +lib+ directory relative 
to your current working directory has the appropriate support files.
=====

Q2 accepts several command line switches; for a complete list, 
use +--help+, e.g.: 

----

bin/q2 --help

usage: Q2
 -C,--config <arg>                 Configuration bundle
 -c,--command <arg>                Command to execute
 -d,--deploydir <arg>              Deployment directory
 -e,--encrypt <arg>                Encrypt configuration bundle
 -h,--help                         Usage information
 -i,--cli                          Command Line Interface
 -n,--name <arg>                   Optional name (defaults to 'Q2')
 -O,--osgi                         Start experimental OSGi framework
                                   server
 -p,--pid-file <arg>               Store project's pid
 -r,--recursive                    Deploy subdirectories recursively
 -s,--ssh                          Enable SSH server
 -sa,--ssh-authorized-keys <arg>   Path to authorized key file (defaults
                                   to 'cfg/authorized_keys')
 -sh,--ssh-host-key-file <arg>     ssh host key file, defaults to
                                   'cfg/hostkeys.ser'
 -sp,--ssh-port <arg>              ssh port (defaults to 2222)
 -su,--ssh-user <arg>              ssh user (defaults to 'admin')
 -v,--version                      Q2's version
----

Q2 has a reasonable set of defaults so you usually don't have to use 
any argument when calling it. A simple call to +bin/q2+ should look 
like this:

----
<log realm="Q2.system" at="2016-10-16T20:19:41.174">
  <info>
    Q2 started, deployDir=/Users/apr/git/jpos/jpos/build/install/jpos/deploy
  </info>
</log>
----

[TIP]
=====
Please pay attention to the +deployDir+ shown in the previous log
message. In this case, it reads 
+/home/jpos/git/jpos/jpos/build/install/jpos/deploy+

You can override the default deploy directory using the +--deploydir+
(or just +-d+) option when calling Q2.

In this particular case, we are running off the +build/install/jpos+ 
directory, because we called +gradle installApp+ which is handy for
local tests. 
=====

At start up time, Q2 scans the +deploy+ directory looking for
*deployment descriptors* (that we also call *QBean descriptors*).
Those are tiny XML files that are used to start and configure Q2's
services.

The directory is sorted in alphabetical order, providing an easy way
to start services in an ordered way.

Q2 needs a logger, so the first thing it looks for is a logger configuration,
which has a well known QBean descriptor name: *00_logger.xml*. This is
the only special name used by Q2, and is required to provide some
visibility into the start-up process. If there's no +00_logger.xml+
defining the *Q2* logger, Q2 creates one on the fly using a
*SimpleLogListener* that outputs log events to +stdout+.

Having no +00_logger.xml+ file in the +deploy+ directory is similar
to having one with just the following configuration:

[source,xml]
----
<logger name="Q2">
  <log-listener class="org.jpos.util.SimpleLogListener" />
</logger>
----

[NOTE]
======
The default jPOS distribution has two pre-configured files
in the deploy directory:

* +00_logger.xml+
* +99_sysmon.xml+

Sysmon starts the jPOS *SystemMonitor* that outputs useful
system health information every hour which is good to keep handy
in production systems.

Please note that when using the `--cli` command line option that starts the jPOS 
command line interface, the default deploy directory is `deploy-cli` instead of
`deploy`. This is to prevent starting services (such as as logger, system monitor)
typically used in jPOS applications. You can of course use the `--deploydir`
command line option and point it back to the default `deploy` directory.

The *CLI* can also be accessed via SSH using the `--ssh` command line option 
(in that case, the default deploy directory doesn't change).
======

=== Command line options

The +--help+ command line option is self-explanatory,
it shows the list of available options. Same goes for +--version+
it gives you output like this:

----
$ bin/q2 --version

jPOS 2.0.9-SNAPSHOT master/1592701 (2016-10-16 20:17:56 ART) 
...
...

----
followed by the jPOS license in use (see <<appendix_license,license>> for details).

[[cli_commands]]
==== +--cli+
CLI stands for jPOS Command Line Interface. When calling +bin/q2 --cli+ you
should see a prompt like this:

----
$ bin/q2 --cli

q2>
----

Typing 'tab' will give you the list of available commands, e.g.:

----
clr                echo               help               logger_benchmark   
shownr             smconsole          tmmon              version
date               env                install            man                
shutdown           sysmon             tzcheck            deploy             
exit               license            mem                sleep
tail               uptime
----

The 'man' command can be used to get information about a given command,
i.e.:

----
q2> man clr

Clear screen

----

Commands can be separated by a semi-colon, so you can -- just for fun --
type 

----
q2> clr; echo Hello; sleep 5; echo jPOS

----

CLI commands are very easy to write, they just have
to implement the link:http://jpos.org/doc/javadoc/org/jpos/q2/CLICommand.html[CLICommand]
interface. 

Just to give you an example, the +sleep+ command is implemented like this:

[source,java]
----
public class SLEEP implements CLICommand {
    public void exec(CLIContext cli, String[] args) throws Exception {
        if (args.length > 1) {
            Thread.sleep(Long.parseLong(args[1]) * 1000);
        }
        else {
            cli.println("Usage: sleep number-of-seconds");
        }
    }
}
----

As mentioned above, when you type 'tab', jPOS gives you a list of
commands. This may change in the future (as we move to OSGi and perhaps
its console service) but right now, we have an easy way to detect CLI 
commands: *they live in the +org.jpos.q2.cli+ package*.

If you navigate to 
link:https://github.com/jpos/jPOS/tree/master/jpos/src/main/java/org/jpos/q2/cli[jpos/src/main/java/org/jpos/q2/cli]
you'll see files like:

----
CLR.java
COPYRIGHT.java
DATE.java
ECHO.java
HELP.java
INSTALL.java
LICENSE.java
MAN.java
MEM.java
SHOWNR.java
SHUTDOWN.java
SLEEP.java
SMCONSOLE.java
SYSMON.java
TAIL.java
TMMON.java
UPTIME.java
VERSION.java
----

The command +HELP+ reads the manual pages for a given command from a resource
named after the command and ending with the '.man' extension, so if you 
navigate to
link:https://github.com/jpos/jPOS/tree/master/jpos/src/main/resources/org/jpos/q2/cli[resources]
directory, you'll see files like:

----
CLR.man
INSTALL.man
MEM.man
SHOWNR.man
SHUTDOWN.man
SMCONSOLE.man
TAIL.man
TMMON.man
----

Containing the help text for some commands.

[NOTE]
======
CLI commands become more interesting when combined with the ability 
to "connect" to a JVM running Q2 from a remote location, i.e. using
the `--ssh` command line option.
======

[TIP]
=====
CLI commands use +jLine3+ that supports tab completion and
basic edit capabilities using the cursor, similar to those
of +readline+. Try to type 'tab' while typing a command,
+jLine+ will complete it for you.
=====

Some CLI commands are just little proof-of-concept commands that we wrote
while coding the CLI subsystem in order to test it, but a few deserve
some additional comments:

* *shownr* will give you a useful dump of the +NameRegistrar+
* *sysmon* will give you output similar to the +SystemMonitor+
* *tail*, similar to the Unix command 'tail' allows you to monitor
  the output of a jPOS logger in real-time.
* *tmmon* allows you to monitor the TransactionManager in real-time.
* *smconsole* is a wrapper around the old jPOS security console that
  allows you to call it from the jPOS jar so that you don't have to
  setup the full classpath.
* *install* extracts sample QBean descriptors from jars in the classpath
  and place them in the 'deploy' directory 

[NOTE]
======
The last command 'install' deserves further comment. In jPOS-EE we
build applications off multiple little 'modules' that are distributed
via a Maven repository. Some of those require some configuration files
that are usually placed in the +META-INF/q2/installs+ directory.

If you look inside the jPOS jar, you'll see that the +META-INF/q2/installs+
directory contain sample +deploy/00_logger.xml+ and +deploy/99_sysmon.xml+
that could be easily extracted using the aforementioned +install+ command.
======

==== +--command <arg>+
Can be used to run a CLI command from the command line, e.g.:

----
bin/q2 --command "install --force"
----

==== +--deploydir <arg>+
If you want to use a deploy directory other than the default +deploy+
you can use this +deploydir+ option. This can be useful to run different
environments (i.e. +deploy_prod+ versus +deploy_test+).

==== +--recursive+
This allows you to put some order and hierarchy into your deploy
directory if it becomes too big. You can create sub directories
to group together deployment descriptors associated with different 
subsystems.

==== +--config <arg>+
During the migration from +QSP+ to +Q2+, jPOS users were used to
the monolithic +QSP+ single XML file and while most users
appreciated the value of the fine grained file-per-service
configuration, a few others requested to keep the ability to run
off a single configuration file.

To create a single config file, you can concatenate together multiple
Q2 descriptors and wrap them with an outer root XML element. The
name of the outer element is not defined, you can use anything you
like, i.e: +<q2>+ or +<bundle>+ or any other name.

Here is a sample config:

[source,xml]
----
<q2>
  <logger name="Q2" class="org.jpos.q2.qbean.LoggerAdaptor">
    <log-listener class="org.jpos.util.SimpleLogListener" />
  </logger>

  <sysmon logger="Q2">
   <attr name="sleepTime" type="java.lang.Long">3600000</attr>
   <attr name="detailRequired" type="java.lang.Boolean">true</attr>
  </sysmon>
</q2>
----

Running +bin/q2 --config your-config-file.xml+ will basically
extract each descriptor out of the config file and place it in
the +deploy+ directory before actually starting Q2.

==== +--encrypt <arg>+
There are situations where you want to hide some service
configuration from an occasional lurker. You can encrypt
it using this command. The encryption key can be changed,
but it ultimately is stored inside the program, so this is
not very secure, but it's good enough to keep an operator
from looking at your QBean descriptors.

The technique to encrypt a service is similar to the one used
in the previous command +--config+, you create an XML file 
with the services you want to encrypt, wrapped by an outer
XML root element (again, with any name you want) and call
+bin/q2 --encrypt file-to-encrypt.xml+

If we call +bin/q2 --encrypt /tmp/sample.xml+ the system will
start, but if you look at the +deploy+ directory, you'll see
that the files that describe the logger and sysmon QBeans
now look like this:

[source,xml]
----
<protected-qbean>
  <data>6E6A0A545209A80B4AC2735F3DA72..............
  ....065345C9CC6FEAE4186D1AE8D4D4B2E54FEA1AB4777B3</data>
</protected-qbean>
----

[NOTE]
======
Please consider this a small protection against an occasional observer.
======

