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

=== Building

==== Initial Setup

. Install J2SE 8.0 SDK (or later), which can be downloaded from
 http://www.oracle.com/technetwork/java/javase/downloads/index.html[http://www.oracle.com/technetwork/java/javase/downloads/index.html]

. Make sure that your JAVA_HOME environment variable is set to the newly installed
 JDK location, and that your PATH includes %JAVA_HOME%\bin (windows) or
 $JAVA_HOME$/bin (unix).

. Install Maven 3.0.3 (or later), which can be downloaded from
 http://maven.apache.org/download.html[http://maven.apache.org/download.html]. Make sure that your PATH includes
 the MVN_HOME/bin directory.

==== Building

. Get the code: `git clone https://github.com/apache/unomi.git`
. Change to the top level directory of Apache Unomi source distribution.
. Run
+
[source]
----
     $> mvn clean install
----
+
This will compile Apache Unomi and run all of the tests in the
 Apache Unomi source distribution. Alternatively, you can run
+
[source]
----
     $> mvn -P \!integration-tests clean install
----
+
This will compile Apache Unomi without running the tests and takes less
 time to build.
+
TIP: On a non-English Windows env, the Asciidoctor Maven Plugin may fail to
     generate manuals due to an encoding conversion issue.
     To solve this issue, we recommend setting the *file.encoding* system property
     to _UTF-8_ like the following examples before issuing the commands shown above.
+
[source]
----
     > set MAVEN_OPTS=-Dfile.encoding=UTF-8
     or
     > set MAVEN_OPTS=-Dfile.encoding=UTF-8 -Xmx2048m
     ...
----
+
. The distributions will be available under "package/target" directory.

==== Installing an ElasticSearch server

Starting with version 1.2, Apache Unomi no longer embeds an ElasticSearch server as this is no longer supported by
the developers of ElasticSearch. Therefore you will need to install a standalone ElasticSearch using the following steps:

Download an ElasticSearch version. Here's the version you will need depending
on your version of Apache Unomi.

Apache Unomi &lt;= 1.2 : https://www.elastic.co/downloads/past-releases/elasticsearch-5-1-2[https://www.elastic.co/downloads/past-releases/elasticsearch-5-1-2]
Apache Unomi &gt;= 1.3 : https://www.elastic.co/downloads/past-releases/elasticsearch-5-6-3[https://www.elastic.co/downloads/past-releases/elasticsearch-5-6-3]
Apache Unomi &gt;= 1.5 : https://www.elastic.co/downloads/past-releases/elasticsearch-7-4-2[https://www.elastic.co/downloads/past-releases/elasticsearch-7-4-2]

Uncompress the downloaded package into a directory

In the config/elasticsearch.yml file, uncomment and modify the following line :

[source]
----
cluster.name: contextElasticSearch
----

Launch the server using

[source]
----
bin/elasticsearch (Mac, Linux)
bin\elasticsearch.bat (Windows)
----

Check that the ElasticSearch is up and running by accessing the following URL :

http://localhost:9200[http://localhost:9200]

==== Deploying the generated binary package

The "package" sub-project generates a pre-configured Apache Karaf installation that is the simplest way to get started.
Simply uncompress the package/target/unomi-VERSION.tar.gz (for Linux or Mac OS X) or
 package/target/unomi-VERSION.zip (for Windows) archive into the directory of your choice.

You can then start the server simply by using the command on UNIX/Linux/MacOS X :

[source]
----
./bin/karaf
----

or on Windows shell :

[source]
----
bin\karaf.bat
----

You will then need to launch (only on the first Karaf start) the Apache Unomi packages using the following Apache Karaf
shell command:

[source]
----
unomi:start
----

==== Deploying into an existing Karaf server

This is only needed if you didn't use the generated package. Also, this is the preferred way to install a development
environment if you intend to re-deploy the context server KAR iteratively.

Additional requirements:
* Apache Karaf 4.2.x, http://karaf.apache.org[http://karaf.apache.org]

Before deploying, make sure that you have Apache Karaf properly installed. You will also have to increase the
default maximum memory size and perm gen size by adjusting the following environment values in the bin/setenv(.bat)
files (at the end of the file):

[source]
----
   MY_DIRNAME=`dirname $0`
   MY_KARAF_HOME=`cd "$MY_DIRNAME/.."; pwd`
   export JAVA_MAX_MEM=3G
   export JAVA_MAX_PERM_MEM=384M
----

Install the WAR support, CXF and Karaf Cellar into Karaf by doing the following in the Karaf command line:

[source]
----
   feature:repo-add cxf-jaxrs 3.3.4
   feature:repo-add cellar 4.1.3
   feature:repo-add mvn:org.apache.unomi/unomi-kar/VERSION/xml/features
   feature:install unomi-kar
----

Create a new $MY_KARAF_HOME/etc/org.apache.cxf.osgi.cfg file and put the following property inside :

[source]
----
   org.apache.cxf.servlet.context=/cxs
----

If all went smoothly, you should be able to access the context script here : http://localhost:8181/cxs/cluster[http://localhost:8181/cxs/cluster] .
 You should be able to login with karaf / karaf and see basic server information. If not something went wrong during the install.

==== JDK Selection on Mac OS X

You might need to select the JDK to run the tests in the itests subproject. In order to do so you can list the
installed JDKs with the following command :

[source]
----
/usr/libexec/java_home -V
----

which will output something like this :

[source]
----
Matching Java Virtual Machines (3):
    11.0.5, x86_64:	"OpenJDK 11.0.5"	/Library/Java/JavaVirtualMachines/openjdk-11.jdk/Contents/Home
    1.8.0_181, x86_64:	"Java SE 8"	/Library/Java/JavaVirtualMachines/jdk1.8.0_181.jdk/Contents/Home
    1.7.0_80, x86_64:	"Java SE 7"	/Library/Java/JavaVirtualMachines/jdk1.7.0_80.jdk/Contents/Home

/Library/Java/JavaVirtualMachines/openjdk-11.jdk/Contents/Home
----

You can then select the one you want using :

[source]
----
export JAVA_HOME=`/usr/libexec/java_home -v 1.8.0_181`
----

and then check that it was correctly referenced using:

[source]
----
java -version
----

which should give you a result such as this:

[source]
----
openjdk version "11.0.5" 2019-10-15
OpenJDK Runtime Environment (build 11.0.5+10)
OpenJDK 64-Bit Server VM (build 11.0.5+10, mixed mode)
----

==== Running the integration tests

The integration tests are not executed by default to make build time minimal, but it is recommended to run the
integration tests at least once before using the server to make sure that everything is ok in the build. Another way
to use these tests is to run them from a continuous integration server such as Jenkins, Apache Gump, Atlassian Bamboo or
 others.

Note : the integration tests require a JDK 8 or more recent !

To run the tests simply activate the following profile :

[source]
----
mvn -P integration-tests clean install
----

==== Testing with an example page

A default test page is provided at the following URL:

[source]
----
   http://localhost:8181/index.html
----

This test page will trigger the loading of the /cxs/context.js script, which will try to retrieving the user context
or create a new one if it doesn't exist yet. It also contains an experimental integration with Facebook Login, but it
doesn't yet save the context back to the context server.
