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


CentOS 6.5 build

Install Prerequisites
---------------------
0) Install development tools
    $>yum groupinstall 'Development Tools'

1) CMAKE 3
    $> yum install cmake3

2.1) Download protobuf 3.11 from :
    https://github.com/protocolbuffers/protobuf/releases/download/v3.11.1/protobuf-java-3.11.1.zip

2.2) Install Protobufs
    $> unzip protobuf-java-3.11.1.zip
    $> cd protobuf-3.11.1
    $> ./configure
    $> sudo make
    $> sudo make install

3)
3.1) Install Zookeeper prerequisites
    - autoconf 2.59 or greater (should be installed with dev tools)
    - cppunit 1.10.x or higher

3.1.1) install cppuint
    $> sudo yum install cppunit
    $> sudo yum install cppunit-devel

3.2) Download Zookeeper from :
    - https://archive.apache.org/dist/zookeeper/zookeeper-3.4.6/
    - untar and then follow instructions in ZOOKEEPER_DIR/src/c/README to build and install the client libs

3.3) run autoreconf
    $> autoreconf -if

3.4) Build Zookeeper libs
    $> ./configure --enable-debug --with-syncapi --enable-static --enable-shared
    $> make && sudo make install

4) Install boost. The minimum version required is 1.54, which will probably have to be built from source

    # Build boost for Drill using instruction from readme.boost.
    # Uncomment set(Boost_NAMESPACE drill_boost) line in client/CMakeLists.txt
OR 
    Download and build using boost build. 
    See this link for how to build: http://www.boost.org/doc/libs/1_54_0/more/getting_started/unix-variants.html#prepare-to-use-a-boost-library-binary 
    After building boost from the source, you will need to specify where to find it by adding -DBOOST_ROOT=<boost install directory> to your cmake command

5) Install or  build Cyrus SASL 
   To Install 
       yum install cyrus-sasl-devel cyrus-sasl-gssapi
   libs are installed in /usr/lib64/sasl2
   includes are installed in /usr/include

   To build your own 
   See readme.sasl for instructions

6) Install OpenSSL
   yum install openssl-devel openssl


(Optional) Refresh protobuf source files
----------------------------------------
When changes have been introduced to the protocol module, you might need to refresh the protobuf C++ source files too.
    $> cd DRILL_DIR/contrib/native/client
    $> mkdir build
    $> cd build && cmake3 -G "Unix Makefiles" ..
    $> make cpProtobufs

Open a pull request with the changes to DRILL_DIR/contrib/native/client/src/protobuf

Build drill client
-------------------
    $> cd DRILL_DIR/contrib/native/client
    $> mkdir build
    $> cd build && cmake3 -G "Unix Makefiles" -D CMAKE_BUILD_TYPE=Debug ..
    $> make

Test
----
Run query submitter from the command line
    $> querySubmitter query='SELECT * FROM cp.`employee.json` LIMIT 20' type=sql connectStr=local=10.250.0.146:31010 api=async logLevel=trace user=yourUserName password=yourPassWord

Valgrind
--------
Examples to run Valgrind and see the log in Valkyrie
    $> valgrind --leak-check=yes --xml=yes --xml-file=qs-vg-log-a.xml querySubmitter query='SELECT * FROM cp.`employee.json` LIMIT 20' type=sql connectStr=local=10.250.0.146:31010 api=async logLevel=trace
    $> valkyrie -l qs-vg-log-a.xml


