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 019package org.apache.hadoop.hdfs.server.protocol; 020 021import java.io.IOException; 022 023import org.apache.hadoop.classification.InterfaceAudience; 024import org.apache.hadoop.classification.InterfaceStability; 025import org.apache.hadoop.hdfs.protocol.HdfsConstants; 026import org.apache.hadoop.hdfs.server.common.Storage; 027import org.apache.hadoop.hdfs.server.common.StorageInfo; 028import org.apache.hadoop.hdfs.server.common.HdfsServerConstants.NodeType; 029import org.apache.hadoop.hdfs.server.namenode.NNStorage; 030import org.apache.hadoop.util.VersionInfo; 031 032import com.google.common.annotations.VisibleForTesting; 033import com.google.common.base.Preconditions; 034 035/** 036 * NamespaceInfo is returned by the name-node in reply 037 * to a data-node handshake. 038 * 039 */ 040@InterfaceAudience.Private 041@InterfaceStability.Evolving 042public class NamespaceInfo extends StorageInfo { 043 final String buildVersion; 044 String blockPoolID = ""; // id of the block pool 045 String softwareVersion; 046 long capabilities; 047 048 // only authoritative on the server-side to determine advertisement to 049 // clients. enum will update the supported values 050 private static final long CAPABILITIES_SUPPORTED = getSupportedCapabilities(); 051 052 private static long getSupportedCapabilities() { 053 long mask = 0; 054 for (Capability c : Capability.values()) { 055 if (c.supported) { 056 mask |= c.mask; 057 } 058 } 059 return mask; 060 } 061 062 public enum Capability { 063 UNKNOWN(false), 064 STORAGE_BLOCK_REPORT_BUFFERS(true); // use optimized ByteString buffers 065 private final boolean supported; 066 private final long mask; 067 Capability(boolean isSupported) { 068 supported = isSupported; 069 int bits = ordinal() - 1; 070 mask = (bits < 0) ? 0 : (1L << bits); 071 } 072 public long getMask() { 073 return mask; 074 } 075 } 076 077 // defaults to enabled capabilites since this ctor is for server 078 public NamespaceInfo() { 079 super(NodeType.NAME_NODE); 080 buildVersion = null; 081 capabilities = CAPABILITIES_SUPPORTED; 082 } 083 084 // defaults to enabled capabilites since this ctor is for server 085 public NamespaceInfo(int nsID, String clusterID, String bpID, 086 long cT, String buildVersion, String softwareVersion) { 087 this(nsID, clusterID, bpID, cT, buildVersion, softwareVersion, 088 CAPABILITIES_SUPPORTED); 089 } 090 091 // for use by server and/or client 092 public NamespaceInfo(int nsID, String clusterID, String bpID, 093 long cT, String buildVersion, String softwareVersion, 094 long capabilities) { 095 super(HdfsConstants.NAMENODE_LAYOUT_VERSION, nsID, clusterID, cT, 096 NodeType.NAME_NODE); 097 blockPoolID = bpID; 098 this.buildVersion = buildVersion; 099 this.softwareVersion = softwareVersion; 100 this.capabilities = capabilities; 101 } 102 103 public NamespaceInfo(int nsID, String clusterID, String bpID, 104 long cT) { 105 this(nsID, clusterID, bpID, cT, Storage.getBuildVersion(), 106 VersionInfo.getVersion()); 107 } 108 109 public long getCapabilities() { 110 return capabilities; 111 } 112 113 @VisibleForTesting 114 public void setCapabilities(long capabilities) { 115 this.capabilities = capabilities; 116 } 117 118 public boolean isCapabilitySupported(Capability capability) { 119 Preconditions.checkArgument(capability != Capability.UNKNOWN, 120 "cannot test for unknown capability"); 121 long mask = capability.getMask(); 122 return (capabilities & mask) == mask; 123 } 124 125 public String getBuildVersion() { 126 return buildVersion; 127 } 128 129 public String getBlockPoolID() { 130 return blockPoolID; 131 } 132 133 public String getSoftwareVersion() { 134 return softwareVersion; 135 } 136 137 @Override 138 public String toString(){ 139 return super.toString() + ";bpid=" + blockPoolID; 140 } 141 142 public void validateStorage(NNStorage storage) throws IOException { 143 if (layoutVersion != storage.getLayoutVersion() || 144 namespaceID != storage.getNamespaceID() || 145 cTime != storage.cTime || 146 !clusterID.equals(storage.getClusterID()) || 147 !blockPoolID.equals(storage.getBlockPoolID())) { 148 throw new IOException("Inconsistent namespace information:\n" + 149 "NamespaceInfo has:\n" + 150 "LV=" + layoutVersion + ";" + 151 "NS=" + namespaceID + ";" + 152 "cTime=" + cTime + ";" + 153 "CID=" + clusterID + ";" + 154 "BPID=" + blockPoolID + 155 ".\nStorage has:\n" + 156 "LV=" + storage.getLayoutVersion() + ";" + 157 "NS=" + storage.getNamespaceID() + ";" + 158 "cTime=" + storage.getCTime() + ";" + 159 "CID=" + storage.getClusterID() + ";" + 160 "BPID=" + storage.getBlockPoolID() + "."); 161 } 162 } 163}