#!/bin/bash

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

# Starts a Sqoop metastore 
#
# chkconfig: 2345 90 10
# description: Sqoop allows easy imports and exports of data sets between \
# databases and the Hadoop Distributed File System (HDFS). The Sqoop \
# metastore allows users to define saved jobs for repeated execution and \
# share them with other users of the cluster.
# processname: java
#
### BEGIN INIT INFO
# Provides:          Sqoop
# Required-Start:    $network $local_fs $remote_fs
# Required-Stop:     $remote_fs
# Should-Start:      $named
# Should-Stop:
# Default-Start:     3 4 5
# Default-Stop:      0 1 2 6
# Short-Description: Sqoop allows easy imports and exports of data sets between databases and the Hadoop Distributed File System (HDFS).
### END INIT INFO

. /lib/lsb/init-functions

# Autodetect JAVA_HOME if not defined
. /usr/lib/bigtop-utils/bigtop-detect-javahome

BIGTOP_DEFAULTS_DIR=${BIGTOP_DEFAULTS_DIR-/etc/default}
[ -n "${BIGTOP_DEFAULTS_DIR}" -a -r ${BIGTOP_DEFAULTS_DIR}/hadoop ] && . ${BIGTOP_DEFAULTS_DIR}/hadoop

STATUS_RUNNING=0
STATUS_DEAD=1
STATUS_DEAD_AND_LOCK=2
STATUS_NOT_RUNNING=3

ERROR_PROGRAM_NOT_INSTALLED=5
ERROR_PROGRAM_NOT_CONFIGURED=6


RETVAL=0
NAME=sqoop-metastore
DESC="Sqoop metastore"
PID_FILE=/var/run/sqoop/sqoop-metastore.pid
LOCKFILE="/var/lock/subsys/sqoop-metastore"
LOGDIR=/var/log/sqoop
SQOOP_BIN_PATH="/usr/lib/sqoop/bin"
USER="sqoop"
GROUP="sqoop"

start() {
  [ -x ${SQOOP_BIN_PATH}/start-metastore.sh ] || exit $ERROR_PROGRAM_NOT_INSTALLED

  # Pid files created in sqoop-specific directory under /var/run.
  # The dir should be recreated first.
  local piddir=`dirname "$PID_FILE"`
  install -d -m 0755 -o $USER -g $GROUP "$piddir"

  log_success_msg "Starting $DESC: "
  start_daemon -u $USER ${SQOOP_BIN_PATH}/start-metastore.sh -p $PID_FILE -l $LOGDIR
  RETVAL=$?
  echo
  [ $RETVAL -eq 0 ] && touch $LOCKFILE
  return $RETVAL
}

stop() {
  [ -x ${SQOOP_BIN_PATH}/stop-metastore.sh ] || exit $ERROR_PROGRAM_NOT_INSTALLED
  log_success_msg "Stopping $DESC: "
  start_daemon -u $USER ${SQOOP_BIN_PATH}/stop-metastore.sh -p $PID_FILE
  RETVAL=$?
  sleep 5
  echo
  [ $RETVAL -eq 0 ] && rm -f $LOCKFILE $PIDFILE
}

restart() {
  stop
  start
}

checkstatus(){
  pidofproc -p $PID_FILE java > /dev/null
  status=$?

  case "$status" in
    $STATUS_RUNNING)
      log_success_msg "$DESC is running"
      ;;
    $STATUS_DEAD)
      log_failure_msg "$DESC is dead and pid file exists"
      ;;
    $STATUS_DEAD_AND_LOCK)
      log_failure_msg "$DESC is dead and lock file exists"
      ;;
    $STATUS_NOT_RUNNING)
      log_failure_msg "$DESC is not running"
      ;;
    *)
      log_failure_msg "$DESC status is unknown"
      ;;
  esac
  return $status
}

condrestart(){
  [ -e $LOCKFILE ] && restart || :
}

case "$1" in
  start)
    start
    ;;
  stop)
    stop
    ;;
  status)
    checkstatus
    ;;
  restart)
    restart
    ;;
  condrestart|try-restart)
    condrestart
    ;;
  *)
    echo $"Usage: $0 {start|stop|status|restart|try-restart|condrestart}"
    exit 1
esac

exit $RETVAL
