001 /** 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software 013 * distributed under the License is distributed on an "AS IS" BASIS, 014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018 package org.apache.hadoop.ha; 019 020 import java.io.IOException; 021 import java.net.InetSocketAddress; 022 import java.util.Map; 023 024 import javax.net.SocketFactory; 025 026 import org.apache.hadoop.classification.InterfaceAudience; 027 import org.apache.hadoop.classification.InterfaceStability; 028 import org.apache.hadoop.conf.Configuration; 029 import org.apache.hadoop.fs.CommonConfigurationKeysPublic; 030 import org.apache.hadoop.ha.protocolPB.HAServiceProtocolClientSideTranslatorPB; 031 import org.apache.hadoop.ha.protocolPB.ZKFCProtocolClientSideTranslatorPB; 032 import org.apache.hadoop.net.NetUtils; 033 034 import com.google.common.collect.Maps; 035 036 /** 037 * Represents a target of the client side HA administration commands. 038 */ 039 @InterfaceAudience.Public 040 @InterfaceStability.Evolving 041 public abstract class HAServiceTarget { 042 043 private static final String HOST_SUBST_KEY = "host"; 044 private static final String PORT_SUBST_KEY = "port"; 045 private static final String ADDRESS_SUBST_KEY = "address"; 046 047 /** 048 * @return the IPC address of the target node. 049 */ 050 public abstract InetSocketAddress getAddress(); 051 052 /** 053 * @return the IPC address of the ZKFC on the target node 054 */ 055 public abstract InetSocketAddress getZKFCAddress(); 056 057 /** 058 * @return a Fencer implementation configured for this target node 059 */ 060 public abstract NodeFencer getFencer(); 061 062 /** 063 * @throws BadFencingConfigurationException if the fencing configuration 064 * appears to be invalid. This is divorced from the above 065 * {@link #getFencer()} method so that the configuration can be checked 066 * during the pre-flight phase of failover. 067 */ 068 public abstract void checkFencingConfigured() 069 throws BadFencingConfigurationException; 070 071 /** 072 * @return a proxy to connect to the target HA Service. 073 */ 074 public HAServiceProtocol getProxy(Configuration conf, int timeoutMs) 075 throws IOException { 076 Configuration confCopy = new Configuration(conf); 077 // Lower the timeout so we quickly fail to connect 078 confCopy.setInt(CommonConfigurationKeysPublic.IPC_CLIENT_CONNECT_MAX_RETRIES_KEY, 1); 079 SocketFactory factory = NetUtils.getDefaultSocketFactory(confCopy); 080 return new HAServiceProtocolClientSideTranslatorPB( 081 getAddress(), 082 confCopy, factory, timeoutMs); 083 } 084 085 /** 086 * @return a proxy to the ZKFC which is associated with this HA service. 087 */ 088 public ZKFCProtocol getZKFCProxy(Configuration conf, int timeoutMs) 089 throws IOException { 090 Configuration confCopy = new Configuration(conf); 091 // Lower the timeout so we quickly fail to connect 092 confCopy.setInt(CommonConfigurationKeysPublic.IPC_CLIENT_CONNECT_MAX_RETRIES_KEY, 1); 093 SocketFactory factory = NetUtils.getDefaultSocketFactory(confCopy); 094 return new ZKFCProtocolClientSideTranslatorPB( 095 getZKFCAddress(), 096 confCopy, factory, timeoutMs); 097 } 098 099 public final Map<String, String> getFencingParameters() { 100 Map<String, String> ret = Maps.newHashMap(); 101 addFencingParameters(ret); 102 return ret; 103 } 104 105 /** 106 * Hook to allow subclasses to add any parameters they would like to 107 * expose to fencing implementations/scripts. Fencing methods are free 108 * to use this map as they see fit -- notably, the shell script 109 * implementation takes each entry, prepends 'target_', substitutes 110 * '_' for '.', and adds it to the environment of the script. 111 * 112 * Subclass implementations should be sure to delegate to the superclass 113 * implementation as well as adding their own keys. 114 * 115 * @param ret map which can be mutated to pass parameters to the fencer 116 */ 117 protected void addFencingParameters(Map<String, String> ret) { 118 ret.put(ADDRESS_SUBST_KEY, String.valueOf(getAddress())); 119 ret.put(HOST_SUBST_KEY, getAddress().getHostName()); 120 ret.put(PORT_SUBST_KEY, String.valueOf(getAddress().getPort())); 121 } 122 123 /** 124 * @return true if auto failover should be considered enabled 125 */ 126 public boolean isAutoFailoverEnabled() { 127 return false; 128 } 129 }