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

# Add or remove servers from draining mode via zookeeper 

require 'optparse'
include Java

import org.apache.hadoop.hbase.HBaseConfiguration
import org.apache.hadoop.hbase.client.ConnectionFactory
import org.apache.hadoop.hbase.client.HBaseAdmin
import org.apache.hadoop.hbase.zookeeper.ZKUtil
import org.apache.commons.logging.Log
import org.apache.commons.logging.LogFactory

# Name of this script
NAME = "draining_servers"

# Do command-line parsing
options = {}
optparse = OptionParser.new do |opts|
  opts.banner = "Usage: ./hbase org.jruby.Main #{NAME}.rb [options] add|remove|list <hostname>|<host:port>|<servername> ..."
  opts.separator 'Add remove or list servers in draining mode. Can accept either hostname to drain all region servers' +
                 'in that host, a host:port pair or a host,port,startCode triplet. More than one server can be given separated by space'
  opts.on('-h', '--help', 'Display usage information') do
    puts opts
    exit
  end
  options[:debug] = false
  opts.on('-d', '--debug', 'Display extra debug logging') do
    options[:debug] = true
  end
end
optparse.parse!

# Return array of servernames where servername is hostname+port+startcode
# comma-delimited
def getServers(admin)
  serverInfos = admin.getClusterStatus().getServers()
  servers = []
  for server in serverInfos
    servers << server.getServerName()
  end
  return servers
end

def getServerNames(hostOrServers, config)
  ret = []
  connection = ConnectionFactory.createConnection(config)
  
  for hostOrServer in hostOrServers
    # check whether it is already serverName. No need to connect to cluster
    parts = hostOrServer.split(',')
    if parts.size() == 3
      ret << hostOrServer
    else 
      admin = connection.getAdmin() if not admin
      servers = getServers(admin)

      hostOrServer = hostOrServer.gsub(/:/, ",")
      for server in servers 
        ret << server if server.start_with?(hostOrServer)
      end
    end
  end
  
  admin.close() if admin
  connection.close()
  return ret
end

def addServers(options, hostOrServers)
  config = HBaseConfiguration.create()
  servers = getServerNames(hostOrServers, config)
  
  zkw = org.apache.hadoop.hbase.zookeeper.ZooKeeperWatcher.new(config, "draining_servers", nil)
  parentZnode = zkw.drainingZNode
  
  begin
    for server in servers
      node = ZKUtil.joinZNode(parentZnode, server)
      ZKUtil.createAndFailSilent(zkw, node)
    end
  ensure
    zkw.close()
  end
end

def removeServers(options, hostOrServers)
  config = HBaseConfiguration.create()
  servers = getServerNames(hostOrServers, config)
  
  zkw = org.apache.hadoop.hbase.zookeeper.ZooKeeperWatcher.new(config, "draining_servers", nil)
  parentZnode = zkw.drainingZNode
  
  begin
    for server in servers
      node = ZKUtil.joinZNode(parentZnode, server)
      ZKUtil.deleteNodeFailSilent(zkw, node)
    end
  ensure
    zkw.close()
  end
end

# list servers in draining mode
def listServers(options)
  config = HBaseConfiguration.create()
  
  zkw = org.apache.hadoop.hbase.zookeeper.ZooKeeperWatcher.new(config, "draining_servers", nil)
  parentZnode = zkw.drainingZNode

  servers = ZKUtil.listChildrenNoWatch(zkw, parentZnode)
  servers.each {|server| puts server}
end

hostOrServers = ARGV[1..ARGV.size()]

# Create a logger and disable the DEBUG-level annoying client logging
def configureLogging(options)
  apacheLogger = LogFactory.getLog(NAME)
  # Configure log4j to not spew so much
  unless (options[:debug]) 
    logger = org.apache.log4j.Logger.getLogger("org.apache.hadoop.hbase")
    logger.setLevel(org.apache.log4j.Level::WARN)
    logger = org.apache.log4j.Logger.getLogger("org.apache.zookeeper")
    logger.setLevel(org.apache.log4j.Level::WARN)
  end
  return apacheLogger
end

# Create a logger and save it to ruby global
$LOG = configureLogging(options)
case ARGV[0]
  when 'add'
    if ARGV.length < 2
      puts optparse
      exit 1
    end
    addServers(options, hostOrServers)
  when 'remove'
    if ARGV.length < 2
      puts optparse
      exit 1
    end
    removeServers(options, hostOrServers)
  when 'list'
    listServers(options)
  else
    puts optparse
    exit 3
end
