/** * 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. */ package org.apache.hadoop.hdfs.conf; import static org.apache.hadoop.hdfs.conf.AvatarConfigurationKeys.AVATAR_PROTOCOL_PORT; import static org.apache.hadoop.hdfs.conf.AvatarConfigurationKeys.CLIENT_PROTOCOL_PORT; import static org.apache.hadoop.hdfs.conf.AvatarConfigurationKeys.DATANODE_PROTOCOL_PORT; import static org.apache.hadoop.hdfs.conf.AvatarConfigurationKeys.DFS_AVATARNODE_ONE_ADDRESS; import static org.apache.hadoop.hdfs.conf.AvatarConfigurationKeys.DFS_AVATARNODE_ZERO_ADDRESS; import static org.apache.hadoop.hdfs.conf.AvatarConfigurationKeys.HTTP_PROTOCOL_PORT; import static org.apache.hadoop.hdfs.protocol.FSConstants.DFS_CLUSTER_NAME; import java.io.IOException; import java.net.UnknownHostException; import java.util.Collection; import java.util.LinkedList; import java.util.List; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.hadoop.conf.Configurable; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.hdfs.DFSUtil; import org.apache.hadoop.hdfs.protocol.FSConstants; import org.apache.hadoop.hdfs.protocol.AvatarConstants.InstanceId; import org.apache.zookeeper.KeeperException; import org.apache.zookeeper.data.Stat; /** * This class is responsible for reading configuration with addresses and ports * as separate for all bindable socket address values. * */ public class AvatarNameSpaceAddressManager extends NameSpaceAddressManager { private Log LOG = LogFactory.getLog(getClass()); private static final String[] valuesManaged = new String[] { DFS_AVATARNODE_ZERO_ADDRESS, DFS_AVATARNODE_ONE_ADDRESS, CLIENT_PROTOCOL_PORT, AVATAR_PROTOCOL_PORT, HTTP_PROTOCOL_PORT, DATANODE_PROTOCOL_PORT }; private final String znodePath; public AvatarNameSpaceAddressManager(Configurable confg, String serviceName) { super(confg); znodePath = confg.getConf().get(DFS_CLUSTER_NAME) + "/" + serviceName; nodeZero = new AvatarNodeAddress(InstanceId.NODEZERO, serviceName, confg); nodeOne = new AvatarNodeAddress(InstanceId.NODEONE, serviceName, confg); try { // We would like to update the primary and standby references at construction // but // not throw an exception here. refreshZookeeperInfo(); } catch (IOException ioe) { LOG.error(ioe); } catch (KeeperException kpe) { LOG.error(kpe); } catch (InterruptedException ie) { LOG.error(ie); } } @Override public void setPrimary(InstanceId id) throws IOException { if (id == null) { zkClient.clearPrimary(znodePath); } else { zkClient.registerPrimary(znodePath, id.getZookeeeperValue(), true); } super.setPrimary(id); } @Override public void refreshZookeeperInfo() throws IOException, KeeperException, InterruptedException { String primaryNodeFromZk = zkClient.getPrimaryAvatarAddress(znodePath, new Stat(), false); if (primaryNodeFromZk == null) { // Fail over in progress super.setPrimary(null); } else if (primaryNodeFromZk.equals("zero")) { super.setPrimary(InstanceId.NODEZERO); } else if (primaryNodeFromZk.equals("one")) { super.setPrimary(InstanceId.NODEONE); } else { // inconsistent state DFSUtil.throwAndLogIllegalState("Zookeeper has an invalid value: " + primaryNodeFromZk, LOG); } } @Override public void validateConfigFile(Configuration conf) { Collection<String> allNameServices = DFSUtil.getNameServiceIds(conf); List<String> missingKeys = new LinkedList<String>(); List<String> unWantedKeys = new LinkedList<String>(); if (conf.get(FSConstants.DFS_CLUSTER_NAME) == null) { missingKeys.add(FSConstants.DFS_CLUSTER_NAME); } // Need ALL the federated keys for (String aNameService : allNameServices) { for (String value : valuesManaged) { String expectedKey = value + "." + aNameService; if (conf.get(expectedKey) == null) { missingKeys.add(expectedKey); } } } // Don't want any of the non-federated keys for (String value : valuesManaged) { String unexpectedKey = value; if (conf.get(unexpectedKey) != null) { unWantedKeys.add(unexpectedKey); } } if (missingKeys.isEmpty() && unWantedKeys.isEmpty()) { return; } LOG.error("Add these keys: "); for (String aMissingKey : missingKeys) { LOG.error("+" + aMissingKey); } LOG.error("Remove these keys: "); for (String anUnwantedKey : unWantedKeys) { LOG.error("-" + anUnwantedKey); } DFSUtil.throwAndLogIllegalState("Invalid Configuration file.", LOG); } @Override public String getTxidPath() throws UnknownHostException { return znodePath + ":txid"; } @Override public String getSsidPath() throws UnknownHostException { return znodePath + ":ssid"; } }