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 }