@echo off
@rem/*
@rem * Licensed to the Apache Software Foundation (ASF) under one
@rem * or more contributor license agreements.  See the NOTICE file
@rem * distributed with this work for additional information
@rem * regarding copyright ownership.  The ASF licenses this file
@rem * to you under the Apache License, Version 2.0 (the
@rem * "License"); you may not use this file except in compliance
@rem * with the License.  You may obtain a copy of the License at
@rem *
@rem *     http://www.apache.org/licenses/LICENSE-2.0
@rem *
@rem * Unless required by applicable law or agreed to in writing, software
@rem * distributed under the License is distributed on an "AS IS" BASIS,
@rem * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@rem * See the License for the specific language governing permissions and
@rem * limitations under the License.
@rem */
@rem
@rem The hbase command script.  Based on the hadoop command script putting
@rem in hbase classes, libs and configurations ahead of hadoop's.
@rem
@rem TODO: Narrow the amount of duplicated code.
@rem
@rem Environment Variables:
@rem
@rem   JAVA_HOME        The java implementation to use.  Overrides JAVA_HOME.
@rem
@rem   HBASE_CLASSPATH  Extra Java CLASSPATH entries.
@rem
@rem   HBASE_HEAPSIZE   The maximum amount of heap to use.
@rem                    Default is unset and uses the JVMs default setting
@rem                    (usually 1/4th of the available memory).
@rem
@rem   HBASE_OPTS       Extra Java runtime options.
@rem
@rem   HBASE_CONF_DIR   Alternate conf dir. Default is ${HBASE_HOME}/conf.
@rem
@rem   HBASE_ROOT_LOGGER The root appender. Default is INFO,console
@rem
@rem   JRUBY_HOME       JRuby path: $JRUBY_HOME\lib\jruby.jar should exist.
@rem                    Defaults to the jar packaged with HBase.
@rem
@rem   JRUBY_OPTS       Extra options (eg '--1.9') passed to hbase.
@rem                    Empty by default.
@rem   HBASE_SHELL_OPTS Extra options passed to the hbase shell.
@rem                    Empty by default.


setlocal enabledelayedexpansion

for %%i in (%0) do (
  if not defined HBASE_BIN_PATH (
    set HBASE_BIN_PATH=%%~dpi
  )
)

if "%HBASE_BIN_PATH:~-1%" == "\" (
  set HBASE_BIN_PATH=%HBASE_BIN_PATH:~0,-1%
)

if "%1" == "--help" (
  goto :print_usage
  exit /B 0
)
if "%1" == "-h" (
  goto :print_usage
  exit /B 0
)

rem This will set HBASE_HOME, etc.
set hbase-config-script=%HBASE_BIN_PATH%\hbase-config.cmd
call "%hbase-config-script%" %*
if "%1" == "--config" (
  shift
  shift
)

rem Detect if we are in hbase sources dir
set in_dev_env=false

if exist "%HBASE_HOME%\target" set in_dev_env=true

rem --service is an internal option. used by MSI setup to install HBase as a windows service
if "%1" == "--service" (
   set service_entry=true
   shift
)

set hbase-command=%1
shift

@rem if no args specified, show usage
if "%hbase-command%"=="" (
  goto :print_usage
  endlocal
  goto :eof
)

set JAVA_HEAP_MAX=
set JAVA_OFFHEAP_MAX=

rem check envvars which might override default args
if defined HBASE_HEAPSIZE (
  set JAVA_HEAP_MAX=-Xmx%HBASE_HEAPSIZE%m
)

if defined HBASE_OFFHEAPSIZE (
  set JAVA_OFFHEAP_MAX=-XX:MaxDirectMemory=%HBASE_OFFHEAPSIZE%m
)

set CLASSPATH=%HBASE_CONF_DIR%;%JAVA_HOME%\lib\tools.jar

rem Add maven target directory
set cached_classpath_filename=%HBASE_HOME%\hbase-build-configuration\target\cached_classpath.txt
if "%in_dev_env%"=="true" (

  rem adding maven main classes to classpath
  for /f %%i in ('dir /b "%HBASE_HOME%\hbase-*"') do (
    if exist %%i\target\classes set CLASSPATH=!CLASSPATH!;%%i\target\classes
  )

  rem adding maven test classes to classpath
  rem For developers, add hbase classes to CLASSPATH
  for /f %%i in ('dir /b "%HBASE_HOME%\hbase-*"') do (
    if exist %%i\target\test-classes set CLASSPATH=!CLASSPATH!;%%i\target\test-classes
  )

  if not exist "%cached_classpath_filename%" (
    echo "As this is a development environment, we need %cached_classpath_filename% to be generated from maven (command: mvn install -DskipTests)"
    goto :eof
  )

  for /f "delims=" %%i in ('type "%cached_classpath_filename%"') do set CLASSPATH=%CLASSPATH%;%%i
)

@rem For releases add hbase webapps to CLASSPATH
@rem Webapps must come first else it messes up Jetty
if exist "%HBASE_HOME%\hbase-webapps" (
  set CLASSPATH=%CLASSPATH%;%HBASE_HOME%
)

if exist "%HBASE_HOME%\target\hbase-webapps" (
  set CLASSPATH=%CLASSPATH%;%HBASE_HOME%\target
)

for /F %%f in ('dir /b "%HBASE_HOME%\hbase*.jar" 2^>nul') do (
  if not "%%f:~-11"=="sources.jar" (
    set CLASSPATH=!CLASSPATH!;%HBASE_HOME%\%%f
  )
)

@rem Add libs to CLASSPATH
if exist "%HBASE_HOME%\lib" (
  set CLASSPATH=!CLASSPATH!;%HBASE_HOME%\lib\*
)

@rem Add user-specified CLASSPATH last
if defined HBASE_CLASSPATH (
  set CLASSPATH=%CLASSPATH%;%HBASE_CLASSPATH%
)

@rem Default log directory and file
if not defined HBASE_LOG_DIR (
  set HBASE_LOG_DIR=%HBASE_HOME%\logs
)

if not defined HBASE_LOGFILE (
  set HBASE_LOGFILE=hbase.log
)

set JAVA_PLATFORM=

rem If avail, add Hadoop to the CLASSPATH and to the JAVA_LIBRARY_PATH
set PATH=%PATH%;"%HADOOP_HOME%\bin"
set HADOOP_IN_PATH=hadoop.cmd

if exist "%HADOOP_HOME%\bin\%HADOOP_IN_PATH%" (
  set hadoopCpCommand=call %HADOOP_IN_PATH% classpath 2^>nul
  for /f "eol= delims=" %%i in ('!hadoopCpCommand!') do set CLASSPATH_FROM_HADOOP=%%i
  if defined CLASSPATH_FROM_HADOOP (
    set CLASSPATH=%CLASSPATH%;!CLASSPATH_FROM_HADOOP!
  )
  set HADOOP_CLASSPATH=%CLASSPATH%

  set hadoopJLPCommand=call %HADOOP_IN_PATH% org.apache.hadoop.hbase.util.GetJavaProperty java.library.path 2^>nul
  for /f "eol= delims=" %%i in ('!hadoopJLPCommand!') do set HADOOP_JAVA_LIBRARY_PATH=%%i
  if not defined JAVA_LIBRARY_PATH (
     set JAVA_LIBRARY_PATH=!HADOOP_JAVA_LIBRARY_PATH!
  ) else (
     set JAVA_LIBRARY_PATH=%JAVA_LIBRARY_PATH%;!HADOOP_JAVA_LIBRARY_PATH!
  )
)

if exist "%HBASE_HOME%\build\native" (
  set platformCommand=call %JAVA% -classpath "%CLASSPATH%" org.apache.hadoop.util.PlatformName
  for /f %%i in ('!platformCommand!') do set JAVA_PLATFORM=%%i
  set _PATH_TO_APPEND=%HBASE_HOME%\build\native\!JAVA_PLATFORM!;%HBASE_HOME%\build\native\!JAVA_PLATFORM!\lib
  if not defined JAVA_LIBRARY_PATH (
    set JAVA_LIBRARY_PATH=!_PATH_TO_APPEND!
  ) else (
    set JAVA_LIBRARY_PATH=%JAVA_LIBRARY_PATH%;!_PATH_TO_APPEND!
  )
)

rem This loop would set %hbase-command-arguments%
set _hbasearguments=
:MakeCmdArgsLoop
  if [%1]==[] goto :EndLoop

  if not defined _hbasearguments (
    set _hbasearguments=%1
  ) else (
    set _hbasearguments=!_hbasearguments! %1
  )
  shift
goto :MakeCmdArgsLoop
:EndLoop

set hbase-command-arguments=%_hbasearguments%

@rem figure out which class to run
set corecommands=shell master regionserver thrift thrift2 rest avro hlog wal hbck hfile zookeeper zkcli mapredcp
for %%i in ( %corecommands% ) do (
  if "%hbase-command%"=="%%i" set corecommand=true
)

if defined corecommand (
  call :%hbase-command% %hbase-command-arguments%
) else (
  if "%hbase-command%" == "classpath" (
    echo %CLASSPATH%
    goto :eof
  )
  if "%hbase-command%" == "version" (
    set CLASS=org.apache.hadoop.hbase.util.VersionInfo
  ) else (
    set CLASS=%hbase-command%
  )
)

if not defined HBASE_IDENT_STRING (
  set HBASE_IDENT_STRING=%USERNAME%
)

@rem Set the right GC options based on the what we are running
set servercommands=master regionserver thrift thrift2 rest avro zookeeper
for %%i in ( %servercommands% ) do (
  if "%hbase-command%"=="%%i" set servercommand=true
)

if "%servercommand%" == "true" (
  set HBASE_OPTS=%HBASE_OPTS% %SERVER_GC_OPTS%
) else (
  set HBASE_OPTS=%HBASE_OPTS% %CLIENT_GC_OPTS%
)

@rem If HBase is run as a windows service, configure logging
if defined service_entry (
  set HBASE_LOG_PREFIX=hbase-%hbase-command%-%COMPUTERNAME%
  set HBASE_LOGFILE=!HBASE_LOG_PREFIX!.log
  if not defined HBASE_ROOT_LOGGER (
    set HBASE_ROOT_LOGGER=INFO,DRFA
  )
  set HBASE_SECURITY_LOGGER=INFO,DRFAS
  set loggc=!HBASE_LOG_DIR!\!HBASE_LOG_PREFIX!.gc
  set loglog=!HBASE_LOG_DIR!\!HBASE_LOGFILE!

  if "%HBASE_USE_GC_LOGFILE%" == "true" (
    set HBASE_OPTS=%HBASE_OPTS% -Xloggc:"!loggc!"
  )
)

@rem for jruby
@rem (1) for the commands which need jruby (see jruby-commands defined below)
@rem     A. when JRUBY_HOME is defined
@rem        CLASSPATH and HBASE_OPTS are updated according to JRUBY_HOME defined
@rem     B. when JRUBY_HOME is not defined
@rem        add jruby packaged with HBase to CLASSPATH
@rem (2) for other commands, do nothing

@rem check if the commmand needs jruby
set jruby-commands=shell org.jruby.Main
for %%i in ( %jruby-commands% ) do (
  if "%hbase-command%"=="%%i" set jruby-needed=true
)

@rem the command needs jruby
if defined jruby-needed (
  @rem JRUBY_HOME is defined
  if defined JRUBY_HOME (
    set CLASSPATH=%JRUBY_HOME%\lib\jruby.jar;%CLASSPATH%
    set HBASE_OPTS=%HBASE_OPTS% -Djruby.home="%JRUBY_HOME%" -Djruby.lib="%JRUBY_HOME%\lib"
  )

  @rem JRUBY_HOME is not defined
  if not defined JRUBY_HOME (
    @rem in dev environment
    if "%in_dev_env%"=="true" (
      set cached_classpath_jruby_filename=%HBASE_HOME%\hbase-build-configuration\target\cached_classpath_jruby.txt
      if not exist "!cached_classpath_jruby_filename!" (
        echo "As this is a development environment, we need !cached_classpath_jruby_filename! to be generated from maven (command: mvn install -DskipTests)"
        goto :eof
      )
      for /f "delims=" %%i in ('type "!cached_classpath_jruby_filename!"') do set CLASSPATH=%%i;%CLASSPATH%
    )

    @rem not in dev environment
    if "%in_dev_env%"=="false" (
      @rem add jruby packaged with HBase to CLASSPATH
      set JRUBY_PACKAGED_WITH_HBASE=%HBASE_HOME%\lib\ruby\*
      if defined jruby-needed (
        set CLASSPATH=!JRUBY_PACKAGED_WITH_HBASE!;!CLASSPATH!
      )
    )
  )
)

@rem Have JVM dump heap if we run out of memory.  Files will be 'launch directory'
@rem and are named like the following: java_pid21612.hprof. Apparently it does not
@rem 'cost' to have this flag enabled. Its a 1.6 flag only. See:
@rem http://blogs.sun.com/alanb/entry/outofmemoryerror_looks_a_bit_better
set HBASE_OPTS=%HBASE_OPTS% -Dhbase.log.dir="%HBASE_LOG_DIR%"
set HBASE_OPTS=%HBASE_OPTS% -Dhbase.log.file="%HBASE_LOGFILE%"
set HBASE_OPTS=%HBASE_OPTS% -Dhbase.home.dir="%HBASE_HOME%"
set HBASE_OPTS=%HBASE_OPTS% -Dhbase.id.str="%HBASE_IDENT_STRING%"
set HBASE_OPTS=%HBASE_OPTS% -XX:OnOutOfMemoryError="taskkill /F /PID %p"

if not defined HBASE_ROOT_LOGGER (
  set HBASE_ROOT_LOGGER=INFO,console
)
set HBASE_OPTS=%HBASE_OPTS% -Dhbase.root.logger="%HBASE_ROOT_LOGGER%"

if defined JAVA_LIBRARY_PATH (
  set HBASE_OPTS=%HBASE_OPTS% -Djava.library.path="%JAVA_LIBRARY_PATH%"
)

rem Enable security logging on the master and regionserver only
if not defined HBASE_SECURITY_LOGGER (
  set HBASE_SECURITY_LOGGER=INFO,NullAppender
  if "%hbase-command%"=="master" (
    set HBASE_SECURITY_LOGGER=INFO,DRFAS
  )
  if "%hbase-command%"=="regionserver" (
    set HBASE_SECURITY_LOGGER=INFO,DRFAS
  )
)
set HBASE_OPTS=%HBASE_OPTS% -Dhbase.security.logger="%HBASE_SECURITY_LOGGER%"

set HEAP_SETTINGS=%JAVA_HEAP_MAX% %JAVA_OFFHEAP_MAX%
set java_arguments=%HEAP_SETTINGS% %HBASE_OPTS% -classpath "%CLASSPATH%" %CLASS% %hbase-command-arguments%

if defined service_entry (
  call :makeServiceXml %java_arguments%
) else (
  call %JAVA% %java_arguments%
)

endlocal
goto :eof

:shell
  rem find the hbase ruby sources
  if exist "%HBASE_HOME%\lib\ruby" (
    set HBASE_OPTS=%HBASE_OPTS% -Dhbase.ruby.sources="%HBASE_HOME%\lib\ruby"
  ) else (
    set HBASE_OPTS=%HBASE_OPTS% -Dhbase.ruby.sources="%HBASE_HOME%\hbase-shell\src\main\ruby"
  )
  set HBASE_OPTS=%HBASE_OPTS% %HBASE_SHELL_OPTS%

  set CLASS=org.jruby.Main -X+O %JRUBY_OPTS% "%HBASE_HOME%\bin\hirb.rb"
  goto :eof

:master
  set CLASS=org.apache.hadoop.hbase.master.HMaster
  if NOT "%1"=="stop" (
    set HBASE_OPTS=%HBASE_OPTS% %HBASE_MASTER_OPTS%
  )
  goto :eof

:regionserver
  set CLASS=org.apache.hadoop.hbase.regionserver.HRegionServer
  if NOT "%1"=="stop" (
    set HBASE_OPTS=%HBASE_OPTS% %HBASE_REGIONSERVER_OPTS%
  )
  goto :eof

:thrift
  set CLASS=org.apache.hadoop.hbase.thrift.ThriftServer
  if NOT "%1" == "stop" (
    set HBASE_OPTS=%HBASE_OPTS% %HBASE_THRIFT_OPTS%
  )
  goto :eof

:thrift2
  set CLASS=org.apache.hadoop.hbase.thrift2.ThriftServer
  if NOT "%1" == "stop" (
    set HBASE_OPTS=%HBASE_OPTS% %HBASE_THRIFT_OPTS%
  )
  goto :eof

:rest
  set CLASS=org.apache.hadoop.hbase.rest.RESTServer
  if NOT "%1"=="stop" (
    set HBASE_OPTS=%HBASE_OPTS% %HBASE_REST_OPTS%
  )
  goto :eof

:avro
  set CLASS=org.apache.hadoop.hbase.avro.AvroServer
  if NOT "%1"== "stop" (
    set HBASE_OPTS=%HBASE_OPTS% %HBASE_AVRO_OPTS%
  )
  goto :eof

:zookeeper
  set CLASS=org.apache.hadoop.hbase.zookeeper.HQuorumPeer
  if NOT "%1"=="stop" (
    set HBASE_OPTS=%HBASE_OPTS% %HBASE_ZOOKEEPER_OPTS%
  )
  goto :eof

:hbck
  set CLASS=org.apache.hadoop.hbase.util.HBaseFsck
  goto :eof

:wal
  set CLASS=org.apache.hadoop.hbase.wal.WALPrettyPrinter
  goto :eof

:hfile
  set CLASS=org.apache.hadoop.hbase.io.hfile.HFile
  goto :eof

:zkcli
  set CLASS=org.apache.hadoop.hbase.zookeeper.ZKMainServer
  set CLASSPATH=!CLASSPATH!;%HBASE_HOME%\lib\zkcli\*
  goto :eof

:mapredcp
  set CLASS=org.apache.hadoop.hbase.util.MapreduceDependencyClasspathTool
  goto :eof

:makeServiceXml
  set arguments=%*
  @echo ^<service^>
  @echo   ^<id^>%hbase-command%^</id^>
  @echo   ^<name^>%hbase-command%^</name^>
  @echo   ^<description^>This service runs Isotope %hbase-command%^</description^>
  @echo   ^<executable^>%JAVA%^</executable^>
  @echo   ^<arguments^>%arguments%^</arguments^>
  @echo ^</service^>
  goto :eof

:print_usage
  echo Usage: hbase [^<options^>] ^<command^> [^<args^>]
  echo where ^<command^> an option from one of these categories::
  echo Options:
  echo   --config DIR    Configuration direction to use. Default: ./conf
  echo   --help or -h    Print this help message
  echo.
  echo Commands:
  echo Some commands take arguments. Pass no args or -h for usage."
  echo   shell           Run the HBase shell
  echo   hbck            Run the hbase 'fsck' tool
  echo   wal             Write-ahead-log analyzer
  echo   hfile           Store file analyzer
  echo   zkcli           Run the ZooKeeper shell
  echo   master          Run an HBase HMaster node
  echo   regionserver    Run an HBase HRegionServer node
  echo   zookeeper       Run a ZooKeeper server
  echo   rest            Run an HBase REST server
  echo   thrift          Run the HBase Thrift server
  echo   thrift2         Run the HBase Thrift2 server
  echo   classpath       Dump hbase CLASSPATH
  echo   mapredcp        Dump CLASSPATH entries required by mapreduce
  echo   version         Print the version
  echo   CLASSNAME       Run the class named CLASSNAME
  goto :eof
