#!/bin/sh
# 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.


# OPTIONS:
#   -f: start in foreground
#   -p <filename>: log the pid to a file (useful to kill it later)
#   -v: print version string and exit

# CONTROLLING STARTUP:
# 
# This script relies on few environment variables to determine startup
# behavior, those variables are:
#
#   CLASSPATH -- A Java classpath containing everything necessary to run.
#   JVM_OPTS -- Additional arguments to the JVM for heap size, etc
#   CASSANDRA_CONF -- Directory containing Cassandra configuration files.
#
# As a convenience, a fragment of shell is sourced in order to set one or
# more of these variables. This so-called `include' can be placed in a 
# number of locations and will be searched for in order. The lowest 
# priority search path is the same directory as the startup script, and
# since this is the location of the sample in the project tree, it should
# almost work Out Of The Box.
#
# Any serious use-case though will likely require customization of the
# include. For production installations, it is recommended that you copy
# the sample to one of /usr/share/cassandra/cassandra.in.sh,
# /usr/local/share/cassandra/cassandra.in.sh, or 
# /opt/cassandra/cassandra.in.sh and make your modifications there.
#
# Another option is to specify the full path to the include file in the
# environment. For example:
#
#   $ CASSANDRA_INCLUDE=/path/to/in.sh cassandra -p /var/run/cass.pid
#
# Note: This is particularly handy for running multiple instances on a 
# single installation, or for quick tests.
#
# Finally, developers and enthusiasts who frequently run from an SVN 
# checkout, and do not want to locally modify bin/cassandra.in.sh, can put
# a customized include file at ~/.cassandra.in.sh.
#
# If you would rather configure startup entirely from the environment, you
# can disable the include by exporting an empty CASSANDRA_INCLUDE, or by 
# ensuring that no include files exist in the aforementioned search list.
# Be aware that you will be entirely responsible for populating the needed
# environment variables.

# NB: Developers should be aware that this script should remain compatible with
# POSIX sh and Solaris sh. This means, in particular, no $(( )) and no $( ).

# If an include wasn't specified in the environment, then search for one...
if [ "x$CASSANDRA_INCLUDE" = "x" ]; then
    # Locations (in order) to use when searching for an include file.
    for include in "`dirname "$0"`/cassandra.in.sh" \
                   "$HOME/.cassandra.in.sh" \
                   /usr/share/cassandra/cassandra.in.sh \
                   /usr/local/share/cassandra/cassandra.in.sh \
                   /opt/cassandra/cassandra.in.sh; do
        if [ -r "$include" ]; then
            . "$include"
            break
        fi
    done
# ...otherwise, source the specified include.
elif [ -r "$CASSANDRA_INCLUDE" ]; then
    . "$CASSANDRA_INCLUDE"
fi

# Use JAVA_HOME if set, otherwise look for java in PATH
if [ -n "$JAVA_HOME" ]; then
    # Why we can't have nice things: Solaris combines x86 and x86_64
    # installations in the same tree, using an unconventional path for the
    # 64bit JVM.  Since we prefer 64bit, search the alternate path first,
    # (see https://issues.apache.org/jira/browse/CASSANDRA-4638).
    for java in "$JAVA_HOME"/bin/amd64/java "$JAVA_HOME"/bin/java; do
        if [ -x "$java" ]; then
            JAVA="$java"
            break
        fi
    done
else
    JAVA=java
fi

if [ -z $JAVA ] ; then
    echo Unable to find java executable. Check JAVA_HOME and PATH environment variables. > /dev/stderr
    exit 1;
fi

# If numactl is available, use it. For Cassandra, the priority is to
# avoid disk I/O. Even for the purpose of CPU efficiency, we don't
# really have CPU<->data affinity anyway. Also, empirically test that numactl
# works before trying to use it (CASSANDRA-3245).
NUMACTL_ARGS="--interleave=all"
if which numactl >/dev/null 2>/dev/null && numactl $NUMACTL_ARGS ls / >/dev/null 2>/dev/null
then
    NUMACTL="numactl $NUMACTL_ARGS"
else
    NUMACTL=""
fi

if [ -z "$CASSANDRA_CONF" -o -z "$CLASSPATH" ]; then
    echo "You must set the CASSANDRA_CONF and CLASSPATH vars" >&2
    exit 1
fi

if [ -f "$CASSANDRA_CONF/cassandra-env.sh" ]; then
    . "$CASSANDRA_CONF/cassandra-env.sh"
fi

# Special-case path variables.
case "`uname`" in
    CYGWIN*) 
        CLASSPATH=`cygpath -p -w "$CLASSPATH"`
        CASSANDRA_CONF=`cygpath -p -w "$CASSANDRA_CONF"`
    ;;
esac

launch_service()
{
    pidpath="$1"
    foreground="$2"
    props="$3"
    class="$4"
    cassandra_parms="-Dlogback.configurationFile=logback.xml"
    cassandra_parms="$cassandra_parms -Dcassandra.logdir=$CASSANDRA_HOME/logs"
    cassandra_parms="$cassandra_parms -Dcassandra.storagedir=$cassandra_storagedir"

    if [ "x$pidpath" != "x" ]; then
        cassandra_parms="$cassandra_parms -Dcassandra-pidfile=$pidpath"
    fi

    # The cassandra-foreground option will tell CassandraDaemon not
    # to close stdout/stderr, but it's up to us not to background.
    if [ "x$foreground" != "x" ]; then
        cassandra_parms="$cassandra_parms -Dcassandra-foreground=yes"
        exec $NUMACTL "$JAVA" $JVM_OPTS $cassandra_parms -cp "$CLASSPATH" $props "$class"
    # Startup CassandraDaemon, background it, and write the pid.
    else
		# For DUCC put the java command on stdout
        echo Launch Cassandra: "$JAVA" $JVM_OPTS $cassandra_parms -cp "$CLASSPATH" $props "$class"
        exec $NUMACTL "$JAVA" $JVM_OPTS $cassandra_parms -cp "$CLASSPATH" $props "$class" <&- &
        [ ! -z "$pidpath" ] && printf "%d" $! > "$pidpath"
        true
    fi

    return $?
}

# Parse any command line options.
args=`getopt vfhp:bD:H:E: "$@"`
eval set -- "$args"

classname="org.apache.cassandra.service.CassandraDaemon"

while true; do
    case "$1" in
        -p)
            pidfile="$2"
            shift 2
        ;;
        -f)
            foreground="yes"
            shift
        ;;
        -h)
            echo "Usage: $0 [-f] [-h] [-p pidfile] [-H dumpfile] [-E errorfile]"
            exit 0
        ;;
        -v)
            "$JAVA" -cp "$CLASSPATH" org.apache.cassandra.tools.GetVersion
            exit 0
        ;;
        -D)
            properties="$properties -D$2"
            shift 2
        ;;
        -H)
            properties="$properties -XX:HeapDumpPath=$2"
            shift 2
        ;;
        -E)
            properties="$properties -XX:ErrorFile=$2"
            shift 2
        ;;
        --)
            shift
            break
        ;;
        *)
            echo "Error parsing arguments!" >&2
            exit 1
        ;;
    esac
done

# see CASSANDRA-7254
"$JAVA" -cp "$CLASSPATH" $JVM_OPTS 2>&1 | grep -q 'Error: Exception thrown by the agent : java.lang.NullPointerException'
if [ $? -ne "1" ]; then 
    echo Unable to bind JMX, is Cassandra already running?
    exit 1;
fi

# Start up the service
launch_service "$pidfile" "$foreground" "$properties" "$classname"

exit $?

# vi:ai sw=4 ts=4 tw=0 et
