/** * 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.protocol; import java.io.DataInput; import java.io.DataOutput; import java.io.IOException; import com.facebook.swift.codec.ThriftConstructor; import com.facebook.swift.codec.ThriftField; import com.facebook.swift.codec.ThriftStruct; import org.apache.hadoop.io.UTF8; import org.apache.hadoop.io.WritableComparable; /** * DatanodeID is composed of the data node * name (hostname:portNumber) and the data storage ID, * which it currently represents. * */ @ThriftStruct public class DatanodeID implements WritableComparable<DatanodeID> { public static final DatanodeID[] EMPTY_ARRAY = {}; public String name; /// hostname:portNumber public String storageID; /// unique per cluster storageID protected int infoPort; /// the port where the infoserver is running public int ipcPort; /// the port where the ipc server is running /** Equivalent to DatanodeID(""). */ public DatanodeID() {this("");} /** Equivalent to DatanodeID(nodeName, "", -1, -1). */ public DatanodeID(String nodeName) {this(nodeName, "", -1, -1);} /** * DatanodeID copy constructor * * @param from */ public DatanodeID(DatanodeID from) { this(from.getName(), from.getStorageID(), from.getInfoPort(), from.getIpcPort()); } /** * Create DatanodeID * @param name (hostname:portNumber) * @param storageID data storage ID * @param infoPort info server port * @param ipcPort ipc server port */ @ThriftConstructor public DatanodeID(@ThriftField(1) String name, @ThriftField(2) String storageID, @ThriftField(3) int infoPort, @ThriftField(4) int ipcPort) { this.name = name; this.storageID = storageID; this.infoPort = infoPort; this.ipcPort = ipcPort; } /** * @return hostname:portNumber. */ @ThriftField(1) public String getName() { return name; } /** * @return data storage ID. */ @ThriftField(2) public String getStorageID() { return this.storageID; } /** * @return infoPort (the port at which the HTTP server bound to) */ @ThriftField(3) public int getInfoPort() { if (infoPort < 0) return 50075; // default port return infoPort; } /** * @return ipcPort (the port at which the IPC server bound to) */ @ThriftField(4) public int getIpcPort() { return ipcPort; } /** * sets the data storage ID. */ public void setStorageID(String storageID) { this.storageID = storageID; } /** * @return hostname and no :portNumber. */ public String getHost() { int colon = name.indexOf(":"); if (colon < 0) { return name; } else { return name.substring(0, colon); } } public int getPort() { int colon = name.indexOf(":"); if (colon < 0) { return 50010; // default port. } return Integer.parseInt(name.substring(colon+1)); } public boolean equals(Object to) { if (this == to) { return true; } if (!(to instanceof DatanodeID)) { return false; } return (name.equals(((DatanodeID)to).getName()) && storageID.equals(((DatanodeID)to).getStorageID())); } public int hashCode() { return name.hashCode()^ storageID.hashCode(); } public String toString() { return name; } /** * Update fields when a new registration request comes in. * Note that this does not update storageID. */ public void updateRegInfo(DatanodeID nodeReg) { name = nodeReg.getName(); infoPort = nodeReg.getInfoPort(); ipcPort = nodeReg.getIpcPort(); // update any more fields added in future. } /** Comparable. * Basis of compare is the String name (host:portNumber) only. * @param that * @return as specified by Comparable. */ public int compareTo(DatanodeID that) { return name.compareTo(that.getName()); } ///////////////////////////////////////////////// // Writable ///////////////////////////////////////////////// /** {@inheritDoc} */ public void write(DataOutput out) throws IOException { UTF8.writeStringOpt(out, name); UTF8.writeStringOpt(out, storageID); out.writeShort(infoPort); } /** {@inheritDoc} */ public void readFields(DataInput in) throws IOException { name = UTF8.readString(in); storageID = UTF8.readString(in); // the infoPort read could be negative, if the port is a large number (more // than 15 bits in storage size (but less than 16 bits). // So chop off the first two bytes (and hence the signed bits) before // setting the field. this.infoPort = in.readShort() & 0x0000ffff; } public static void write(DataOutput out, DatanodeID elem) throws IOException { DatanodeID node = new DatanodeID(elem); node.write(out); } public static DatanodeID read(DataInput in) throws IOException { DatanodeID node = new DatanodeID(); node.readFields(in); return node; } }