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.net.NetUtils;
032
033 import com.google.common.collect.Maps;
034
035 /**
036 * Represents a target of the client side HA administration commands.
037 */
038 @InterfaceAudience.Public
039 @InterfaceStability.Evolving
040 public abstract class HAServiceTarget {
041
042 private static final String HOST_SUBST_KEY = "host";
043 private static final String PORT_SUBST_KEY = "port";
044 private static final String ADDRESS_SUBST_KEY = "address";
045
046 /**
047 * @return the IPC address of the target node.
048 */
049 public abstract InetSocketAddress getAddress();
050
051 /**
052 * @return a Fencer implementation configured for this target node
053 */
054 public abstract NodeFencer getFencer();
055
056 /**
057 * @throws BadFencingConfigurationException if the fencing configuration
058 * appears to be invalid. This is divorced from the above
059 * {@link #getFencer()} method so that the configuration can be checked
060 * during the pre-flight phase of failover.
061 */
062 public abstract void checkFencingConfigured()
063 throws BadFencingConfigurationException;
064
065 /**
066 * @return a proxy to connect to the target HA Service.
067 */
068 public HAServiceProtocol getProxy(Configuration conf, int timeoutMs)
069 throws IOException {
070 Configuration confCopy = new Configuration(conf);
071 // Lower the timeout so we quickly fail to connect
072 confCopy.setInt(CommonConfigurationKeysPublic.IPC_CLIENT_CONNECT_MAX_RETRIES_KEY, 1);
073 SocketFactory factory = NetUtils.getDefaultSocketFactory(confCopy);
074 return new HAServiceProtocolClientSideTranslatorPB(
075 getAddress(),
076 confCopy, factory, timeoutMs);
077 }
078
079 public final Map<String, String> getFencingParameters() {
080 Map<String, String> ret = Maps.newHashMap();
081 addFencingParameters(ret);
082 return ret;
083 }
084
085 /**
086 * Hook to allow subclasses to add any parameters they would like to
087 * expose to fencing implementations/scripts. Fencing methods are free
088 * to use this map as they see fit -- notably, the shell script
089 * implementation takes each entry, prepends 'target_', substitutes
090 * '_' for '.', and adds it to the environment of the script.
091 *
092 * Subclass implementations should be sure to delegate to the superclass
093 * implementation as well as adding their own keys.
094 *
095 * @param ret map which can be mutated to pass parameters to the fencer
096 */
097 protected void addFencingParameters(Map<String, String> ret) {
098 ret.put(ADDRESS_SUBST_KEY, String.valueOf(getAddress()));
099 ret.put(HOST_SUBST_KEY, getAddress().getHostName());
100 ret.put(PORT_SUBST_KEY, String.valueOf(getAddress().getPort()));
101 }
102 }