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 */
018package org.apache.hadoop.hdfs.protocolPB;
019
020import static com.google.common.base.Preconditions.checkNotNull;
021
022import java.io.EOFException;
023import java.io.IOException;
024import java.io.InputStream;
025import java.util.ArrayList;
026import java.util.Arrays;
027import java.util.EnumSet;
028import java.util.List;
029
030import com.google.common.base.Preconditions;
031import org.apache.hadoop.fs.CacheFlag;
032import org.apache.hadoop.fs.ContentSummary;
033import org.apache.hadoop.fs.CreateFlag;
034import org.apache.hadoop.fs.FsServerDefaults;
035import org.apache.hadoop.fs.Path;
036import org.apache.hadoop.fs.permission.AclEntry;
037import org.apache.hadoop.fs.permission.AclEntryScope;
038import org.apache.hadoop.fs.permission.AclEntryType;
039import org.apache.hadoop.fs.permission.AclStatus;
040import org.apache.hadoop.fs.permission.FsAction;
041import org.apache.hadoop.fs.permission.FsPermission;
042import org.apache.hadoop.ha.HAServiceProtocol.HAServiceState;
043import org.apache.hadoop.hdfs.DFSUtil;
044import org.apache.hadoop.hdfs.ShortCircuitShm.ShmId;
045import org.apache.hadoop.hdfs.ShortCircuitShm.SlotId;
046import org.apache.hadoop.hdfs.StorageType;
047import org.apache.hadoop.hdfs.protocol.Block;
048import org.apache.hadoop.hdfs.protocol.CacheDirectiveEntry;
049import org.apache.hadoop.hdfs.protocol.CacheDirectiveInfo;
050import org.apache.hadoop.hdfs.protocol.CacheDirectiveStats;
051import org.apache.hadoop.hdfs.protocol.CachePoolEntry;
052import org.apache.hadoop.hdfs.protocol.CachePoolInfo;
053import org.apache.hadoop.hdfs.protocol.CachePoolStats;
054import org.apache.hadoop.hdfs.protocol.ClientProtocol;
055import org.apache.hadoop.hdfs.protocol.CorruptFileBlocks;
056import org.apache.hadoop.hdfs.protocol.DatanodeID;
057import org.apache.hadoop.hdfs.protocol.DatanodeInfo;
058import org.apache.hadoop.hdfs.protocol.DatanodeInfo.AdminStates;
059import org.apache.hadoop.hdfs.protocol.DatanodeLocalInfo;
060import org.apache.hadoop.hdfs.protocol.DirectoryListing;
061import org.apache.hadoop.hdfs.protocol.ExtendedBlock;
062import org.apache.hadoop.hdfs.protocol.FsAclPermission;
063import org.apache.hadoop.hdfs.protocol.HdfsConstants.DatanodeReportType;
064import org.apache.hadoop.hdfs.protocol.HdfsConstants.RollingUpgradeAction;
065import org.apache.hadoop.hdfs.protocol.HdfsConstants.SafeModeAction;
066import org.apache.hadoop.hdfs.protocol.HdfsFileStatus;
067import org.apache.hadoop.hdfs.protocol.HdfsLocatedFileStatus;
068import org.apache.hadoop.hdfs.protocol.LocatedBlock;
069import org.apache.hadoop.hdfs.protocol.LocatedBlocks;
070import org.apache.hadoop.hdfs.protocol.RollingUpgradeInfo;
071import org.apache.hadoop.hdfs.protocol.RollingUpgradeStatus;
072import org.apache.hadoop.hdfs.protocol.SnapshotDiffReport;
073import org.apache.hadoop.hdfs.protocol.SnapshotDiffReport.DiffReportEntry;
074import org.apache.hadoop.hdfs.protocol.SnapshotDiffReport.DiffType;
075import org.apache.hadoop.hdfs.protocol.SnapshottableDirectoryStatus;
076import org.apache.hadoop.hdfs.protocol.proto.AclProtos.AclEntryProto;
077import org.apache.hadoop.hdfs.protocol.proto.AclProtos.AclStatusProto;
078import org.apache.hadoop.hdfs.protocol.proto.AclProtos.AclEntryProto.AclEntryScopeProto;
079import org.apache.hadoop.hdfs.protocol.proto.AclProtos.AclEntryProto.AclEntryTypeProto;
080import org.apache.hadoop.hdfs.protocol.proto.AclProtos.AclEntryProto.FsActionProto;
081import org.apache.hadoop.hdfs.protocol.proto.AclProtos.GetAclStatusResponseProto;
082import org.apache.hadoop.hdfs.protocol.proto.ClientNamenodeProtocolProtos;
083import org.apache.hadoop.hdfs.protocol.proto.ClientNamenodeProtocolProtos.CacheDirectiveEntryProto;
084import org.apache.hadoop.hdfs.protocol.proto.ClientNamenodeProtocolProtos.CacheDirectiveInfoExpirationProto;
085import org.apache.hadoop.hdfs.protocol.proto.ClientNamenodeProtocolProtos.CacheDirectiveInfoProto;
086import org.apache.hadoop.hdfs.protocol.proto.ClientNamenodeProtocolProtos.CacheDirectiveStatsProto;
087import org.apache.hadoop.hdfs.protocol.proto.ClientNamenodeProtocolProtos.CacheFlagProto;
088import org.apache.hadoop.hdfs.protocol.proto.ClientNamenodeProtocolProtos.CachePoolEntryProto;
089import org.apache.hadoop.hdfs.protocol.proto.ClientNamenodeProtocolProtos.CachePoolInfoProto;
090import org.apache.hadoop.hdfs.protocol.proto.ClientNamenodeProtocolProtos.CachePoolStatsProto;
091import org.apache.hadoop.hdfs.protocol.proto.ClientNamenodeProtocolProtos.CreateFlagProto;
092import org.apache.hadoop.hdfs.protocol.proto.ClientNamenodeProtocolProtos.DatanodeReportTypeProto;
093import org.apache.hadoop.hdfs.protocol.proto.ClientNamenodeProtocolProtos.GetFsStatsResponseProto;
094import org.apache.hadoop.hdfs.protocol.proto.ClientNamenodeProtocolProtos.RollingUpgradeActionProto;
095import org.apache.hadoop.hdfs.protocol.proto.ClientNamenodeProtocolProtos.RollingUpgradeInfoProto;
096import org.apache.hadoop.hdfs.protocol.proto.ClientNamenodeProtocolProtos.SafeModeActionProto;
097import org.apache.hadoop.hdfs.protocol.proto.ClientNamenodeProtocolProtos.CacheDirectiveInfoProto;
098import org.apache.hadoop.hdfs.protocol.proto.DataTransferProtos.ShortCircuitShmSlotProto;
099import org.apache.hadoop.hdfs.protocol.proto.DataTransferProtos.ShortCircuitShmIdProto;
100import org.apache.hadoop.hdfs.protocol.proto.DatanodeProtocolProtos.BalancerBandwidthCommandProto;
101import org.apache.hadoop.hdfs.protocol.proto.DatanodeProtocolProtos.BlockCommandProto;
102import org.apache.hadoop.hdfs.protocol.proto.DatanodeProtocolProtos.BlockIdCommandProto;
103import org.apache.hadoop.hdfs.protocol.proto.DatanodeProtocolProtos.BlockRecoveryCommandProto;
104import org.apache.hadoop.hdfs.protocol.proto.DatanodeProtocolProtos.DatanodeCommandProto;
105import org.apache.hadoop.hdfs.protocol.proto.DatanodeProtocolProtos.DatanodeRegistrationProto;
106import org.apache.hadoop.hdfs.protocol.proto.DatanodeProtocolProtos.DatanodeStorageProto;
107import org.apache.hadoop.hdfs.protocol.proto.DatanodeProtocolProtos.DatanodeStorageProto.StorageState;
108import org.apache.hadoop.hdfs.protocol.proto.DatanodeProtocolProtos.FinalizeCommandProto;
109import org.apache.hadoop.hdfs.protocol.proto.DatanodeProtocolProtos.KeyUpdateCommandProto;
110import org.apache.hadoop.hdfs.protocol.proto.DatanodeProtocolProtos.NNHAStatusHeartbeatProto;
111import org.apache.hadoop.hdfs.protocol.proto.DatanodeProtocolProtos.ReceivedDeletedBlockInfoProto;
112import org.apache.hadoop.hdfs.protocol.proto.DatanodeProtocolProtos.RegisterCommandProto;
113import org.apache.hadoop.hdfs.protocol.proto.DatanodeProtocolProtos.StorageReportProto;
114import org.apache.hadoop.hdfs.protocol.proto.HdfsProtos;
115import org.apache.hadoop.hdfs.protocol.proto.HdfsProtos.BlockKeyProto;
116import org.apache.hadoop.hdfs.protocol.proto.HdfsProtos.BlockProto;
117import org.apache.hadoop.hdfs.protocol.proto.HdfsProtos.BlockWithLocationsProto;
118import org.apache.hadoop.hdfs.protocol.proto.HdfsProtos.BlocksWithLocationsProto;
119import org.apache.hadoop.hdfs.protocol.proto.HdfsProtos.CheckpointCommandProto;
120import org.apache.hadoop.hdfs.protocol.proto.HdfsProtos.CheckpointSignatureProto;
121import org.apache.hadoop.hdfs.protocol.proto.HdfsProtos.ContentSummaryProto;
122import org.apache.hadoop.hdfs.protocol.proto.HdfsProtos.CorruptFileBlocksProto;
123import org.apache.hadoop.hdfs.protocol.proto.HdfsProtos.DataEncryptionKeyProto;
124import org.apache.hadoop.hdfs.protocol.proto.HdfsProtos.DatanodeIDProto;
125import org.apache.hadoop.hdfs.protocol.proto.HdfsProtos.DatanodeInfoProto;
126import org.apache.hadoop.hdfs.protocol.proto.HdfsProtos.DatanodeInfoProto.AdminState;
127import org.apache.hadoop.hdfs.protocol.proto.HdfsProtos.DatanodeInfosProto;
128import org.apache.hadoop.hdfs.protocol.proto.HdfsProtos.DatanodeLocalInfoProto;
129import org.apache.hadoop.hdfs.protocol.proto.HdfsProtos.DirectoryListingProto;
130import org.apache.hadoop.hdfs.protocol.proto.HdfsProtos.ExportedBlockKeysProto;
131import org.apache.hadoop.hdfs.protocol.proto.HdfsProtos.ExtendedBlockProto;
132import org.apache.hadoop.hdfs.protocol.proto.HdfsProtos.FsPermissionProto;
133import org.apache.hadoop.hdfs.protocol.proto.HdfsProtos.FsServerDefaultsProto;
134import org.apache.hadoop.hdfs.protocol.proto.HdfsProtos.HdfsFileStatusProto;
135import org.apache.hadoop.hdfs.protocol.proto.HdfsProtos.HdfsFileStatusProto.FileType;
136import org.apache.hadoop.hdfs.protocol.proto.HdfsProtos.LocatedBlockProto;
137import org.apache.hadoop.hdfs.protocol.proto.HdfsProtos.LocatedBlockProto.Builder;
138import org.apache.hadoop.hdfs.protocol.proto.HdfsProtos.LocatedBlocksProto;
139import org.apache.hadoop.hdfs.protocol.proto.HdfsProtos.NamenodeCommandProto;
140import org.apache.hadoop.hdfs.protocol.proto.HdfsProtos.NamenodeRegistrationProto;
141import org.apache.hadoop.hdfs.protocol.proto.HdfsProtos.NamenodeRegistrationProto.NamenodeRoleProto;
142import org.apache.hadoop.hdfs.protocol.proto.HdfsProtos.NamespaceInfoProto;
143import org.apache.hadoop.hdfs.protocol.proto.HdfsProtos.RecoveringBlockProto;
144import org.apache.hadoop.hdfs.protocol.proto.HdfsProtos.RemoteEditLogManifestProto;
145import org.apache.hadoop.hdfs.protocol.proto.HdfsProtos.RemoteEditLogProto;
146import org.apache.hadoop.hdfs.protocol.proto.HdfsProtos.ReplicaStateProto;
147import org.apache.hadoop.hdfs.protocol.proto.HdfsProtos.RollingUpgradeStatusProto;
148import org.apache.hadoop.hdfs.protocol.proto.HdfsProtos.SnapshotDiffReportEntryProto;
149import org.apache.hadoop.hdfs.protocol.proto.HdfsProtos.SnapshotDiffReportProto;
150import org.apache.hadoop.hdfs.protocol.proto.HdfsProtos.SnapshottableDirectoryListingProto;
151import org.apache.hadoop.hdfs.protocol.proto.HdfsProtos.SnapshottableDirectoryStatusProto;
152import org.apache.hadoop.hdfs.protocol.proto.HdfsProtos.StorageInfoProto;
153import org.apache.hadoop.hdfs.protocol.proto.HdfsProtos.StorageTypeProto;
154import org.apache.hadoop.hdfs.protocol.proto.HdfsProtos.StorageUuidsProto;
155import org.apache.hadoop.hdfs.protocol.proto.JournalProtocolProtos.JournalInfoProto;
156import org.apache.hadoop.hdfs.security.token.block.BlockKey;
157import org.apache.hadoop.hdfs.security.token.block.BlockTokenIdentifier;
158import org.apache.hadoop.hdfs.security.token.block.DataEncryptionKey;
159import org.apache.hadoop.hdfs.security.token.block.ExportedBlockKeys;
160import org.apache.hadoop.hdfs.security.token.delegation.DelegationTokenIdentifier;
161import org.apache.hadoop.hdfs.server.common.HdfsServerConstants.NamenodeRole;
162import org.apache.hadoop.hdfs.server.common.HdfsServerConstants.NodeType;
163import org.apache.hadoop.hdfs.server.common.HdfsServerConstants.ReplicaState;
164import org.apache.hadoop.hdfs.server.common.StorageInfo;
165import org.apache.hadoop.hdfs.server.namenode.CheckpointSignature;
166import org.apache.hadoop.hdfs.server.namenode.INodeId;
167import org.apache.hadoop.hdfs.server.protocol.BalancerBandwidthCommand;
168import org.apache.hadoop.hdfs.server.protocol.BlockCommand;
169import org.apache.hadoop.hdfs.server.protocol.BlockIdCommand;
170import org.apache.hadoop.hdfs.server.protocol.BlockRecoveryCommand;
171import org.apache.hadoop.hdfs.server.protocol.BlockRecoveryCommand.RecoveringBlock;
172import org.apache.hadoop.hdfs.server.protocol.BlocksWithLocations;
173import org.apache.hadoop.hdfs.server.protocol.BlocksWithLocations.BlockWithLocations;
174import org.apache.hadoop.hdfs.server.protocol.CheckpointCommand;
175import org.apache.hadoop.hdfs.server.protocol.DatanodeCommand;
176import org.apache.hadoop.hdfs.server.protocol.DatanodeProtocol;
177import org.apache.hadoop.hdfs.server.protocol.DatanodeRegistration;
178import org.apache.hadoop.hdfs.server.protocol.DatanodeStorage;
179import org.apache.hadoop.hdfs.server.protocol.DatanodeStorage.State;
180import org.apache.hadoop.hdfs.server.protocol.FinalizeCommand;
181import org.apache.hadoop.hdfs.server.protocol.JournalInfo;
182import org.apache.hadoop.hdfs.server.protocol.KeyUpdateCommand;
183import org.apache.hadoop.hdfs.server.protocol.NNHAStatusHeartbeat;
184import org.apache.hadoop.hdfs.server.protocol.NamenodeCommand;
185import org.apache.hadoop.hdfs.server.protocol.NamenodeRegistration;
186import org.apache.hadoop.hdfs.server.protocol.NamespaceInfo;
187import org.apache.hadoop.hdfs.server.protocol.ReceivedDeletedBlockInfo;
188import org.apache.hadoop.hdfs.server.protocol.ReceivedDeletedBlockInfo.BlockStatus;
189import org.apache.hadoop.hdfs.server.protocol.RegisterCommand;
190import org.apache.hadoop.hdfs.server.protocol.RemoteEditLog;
191import org.apache.hadoop.hdfs.server.protocol.RemoteEditLogManifest;
192import org.apache.hadoop.hdfs.server.protocol.StorageReport;
193import org.apache.hadoop.hdfs.util.ExactSizeInputStream;
194import org.apache.hadoop.io.EnumSetWritable;
195import org.apache.hadoop.io.Text;
196import org.apache.hadoop.security.proto.SecurityProtos.TokenProto;
197import org.apache.hadoop.security.token.Token;
198import org.apache.hadoop.util.DataChecksum;
199
200import com.google.common.base.Preconditions;
201import com.google.common.collect.Lists;
202import com.google.common.primitives.Shorts;
203import com.google.protobuf.ByteString;
204import com.google.protobuf.CodedInputStream;
205
206/**
207 * Utilities for converting protobuf classes to and from implementation classes
208 * and other helper utilities to help in dealing with protobuf.
209 * 
210 * Note that when converting from an internal type to protobuf type, the
211 * converter never return null for protobuf type. The check for internal type
212 * being null must be done before calling the convert() method.
213 */
214public class PBHelper {
215  private static final RegisterCommandProto REG_CMD_PROTO = 
216      RegisterCommandProto.newBuilder().build();
217  private static final RegisterCommand REG_CMD = new RegisterCommand();
218
219  private static final AclEntryScope[] ACL_ENTRY_SCOPE_VALUES =
220      AclEntryScope.values();
221  private static final AclEntryType[] ACL_ENTRY_TYPE_VALUES =
222      AclEntryType.values();
223  private static final FsAction[] FSACTION_VALUES =
224      FsAction.values();
225
226  private PBHelper() {
227    /** Hidden constructor */
228  }
229
230  public static ByteString getByteString(byte[] bytes) {
231    return ByteString.copyFrom(bytes);
232  }
233
234  private static <T extends Enum<T>, U extends Enum<U>> U castEnum(T from, U[] to) {
235    return to[from.ordinal()];
236  }
237
238  public static NamenodeRole convert(NamenodeRoleProto role) {
239    switch (role) {
240    case NAMENODE:
241      return NamenodeRole.NAMENODE;
242    case BACKUP:
243      return NamenodeRole.BACKUP;
244    case CHECKPOINT:
245      return NamenodeRole.CHECKPOINT;
246    }
247    return null;
248  }
249
250  public static NamenodeRoleProto convert(NamenodeRole role) {
251    switch (role) {
252    case NAMENODE:
253      return NamenodeRoleProto.NAMENODE;
254    case BACKUP:
255      return NamenodeRoleProto.BACKUP;
256    case CHECKPOINT:
257      return NamenodeRoleProto.CHECKPOINT;
258    }
259    return null;
260  }
261
262  public static StorageInfoProto convert(StorageInfo info) {
263    return StorageInfoProto.newBuilder().setClusterID(info.getClusterID())
264        .setCTime(info.getCTime()).setLayoutVersion(info.getLayoutVersion())
265        .setNamespceID(info.getNamespaceID()).build();
266  }
267
268  public static StorageInfo convert(StorageInfoProto info, NodeType type) {
269    return new StorageInfo(info.getLayoutVersion(), info.getNamespceID(),
270        info.getClusterID(), info.getCTime(), type);
271  }
272
273  public static NamenodeRegistrationProto convert(NamenodeRegistration reg) {
274    return NamenodeRegistrationProto.newBuilder()
275        .setHttpAddress(reg.getHttpAddress()).setRole(convert(reg.getRole()))
276        .setRpcAddress(reg.getAddress())
277        .setStorageInfo(convert((StorageInfo) reg)).build();
278  }
279
280  public static NamenodeRegistration convert(NamenodeRegistrationProto reg) {
281    StorageInfo si = convert(reg.getStorageInfo(), NodeType.NAME_NODE);
282    return new NamenodeRegistration(reg.getRpcAddress(), reg.getHttpAddress(),
283        si, convert(reg.getRole()));
284  }
285
286  // DatanodeId
287  public static DatanodeID convert(DatanodeIDProto dn) {
288    return new DatanodeID(dn.getIpAddr(), dn.getHostName(), dn.getDatanodeUuid(),
289        dn.getXferPort(), dn.getInfoPort(), dn.hasInfoSecurePort() ? dn
290        .getInfoSecurePort() : 0, dn.getIpcPort());
291  }
292
293  public static DatanodeIDProto convert(DatanodeID dn) {
294    // For wire compatibility with older versions we transmit the StorageID
295    // which is the same as the DatanodeUuid. Since StorageID is a required
296    // field we pass the empty string if the DatanodeUuid is not yet known.
297    return DatanodeIDProto.newBuilder()
298        .setIpAddr(dn.getIpAddr())
299        .setHostName(dn.getHostName())
300        .setXferPort(dn.getXferPort())
301        .setDatanodeUuid(dn.getDatanodeUuid() != null ? dn.getDatanodeUuid() : "")
302        .setInfoPort(dn.getInfoPort())
303        .setInfoSecurePort(dn.getInfoSecurePort())
304        .setIpcPort(dn.getIpcPort()).build();
305  }
306
307  // Arrays of DatanodeId
308  public static DatanodeIDProto[] convert(DatanodeID[] did) {
309    if (did == null)
310      return null;
311    final int len = did.length;
312    DatanodeIDProto[] result = new DatanodeIDProto[len];
313    for (int i = 0; i < len; ++i) {
314      result[i] = convert(did[i]);
315    }
316    return result;
317  }
318  
319  public static DatanodeID[] convert(DatanodeIDProto[] did) {
320    if (did == null) return null;
321    final int len = did.length;
322    DatanodeID[] result = new DatanodeID[len];
323    for (int i = 0; i < len; ++i) {
324      result[i] = convert(did[i]);
325    }
326    return result;
327  }
328  
329  // Block
330  public static BlockProto convert(Block b) {
331    return BlockProto.newBuilder().setBlockId(b.getBlockId())
332        .setGenStamp(b.getGenerationStamp()).setNumBytes(b.getNumBytes())
333        .build();
334  }
335
336  public static Block convert(BlockProto b) {
337    return new Block(b.getBlockId(), b.getNumBytes(), b.getGenStamp());
338  }
339
340  public static BlockWithLocationsProto convert(BlockWithLocations blk) {
341    return BlockWithLocationsProto.newBuilder()
342        .setBlock(convert(blk.getBlock()))
343        .addAllDatanodeUuids(Arrays.asList(blk.getDatanodeUuids()))
344        .addAllStorageUuids(Arrays.asList(blk.getStorageIDs())).build();
345  }
346
347  public static BlockWithLocations convert(BlockWithLocationsProto b) {
348    final List<String> datanodeUuids = b.getDatanodeUuidsList();
349    final List<String> storageUuids = b.getStorageUuidsList();
350    return new BlockWithLocations(convert(b.getBlock()),
351        datanodeUuids.toArray(new String[datanodeUuids.size()]),
352        storageUuids.toArray(new String[storageUuids.size()]));
353  }
354
355  public static BlocksWithLocationsProto convert(BlocksWithLocations blks) {
356    BlocksWithLocationsProto.Builder builder = BlocksWithLocationsProto
357        .newBuilder();
358    for (BlockWithLocations b : blks.getBlocks()) {
359      builder.addBlocks(convert(b));
360    }
361    return builder.build();
362  }
363
364  public static BlocksWithLocations convert(BlocksWithLocationsProto blocks) {
365    List<BlockWithLocationsProto> b = blocks.getBlocksList();
366    BlockWithLocations[] ret = new BlockWithLocations[b.size()];
367    int i = 0;
368    for (BlockWithLocationsProto entry : b) {
369      ret[i++] = convert(entry);
370    }
371    return new BlocksWithLocations(ret);
372  }
373
374  public static BlockKeyProto convert(BlockKey key) {
375    byte[] encodedKey = key.getEncodedKey();
376    ByteString keyBytes = ByteString.copyFrom(encodedKey == null ? 
377        DFSUtil.EMPTY_BYTES : encodedKey);
378    return BlockKeyProto.newBuilder().setKeyId(key.getKeyId())
379        .setKeyBytes(keyBytes).setExpiryDate(key.getExpiryDate()).build();
380  }
381
382  public static BlockKey convert(BlockKeyProto k) {
383    return new BlockKey(k.getKeyId(), k.getExpiryDate(), k.getKeyBytes()
384        .toByteArray());
385  }
386
387  public static ExportedBlockKeysProto convert(ExportedBlockKeys keys) {
388    ExportedBlockKeysProto.Builder builder = ExportedBlockKeysProto
389        .newBuilder();
390    builder.setIsBlockTokenEnabled(keys.isBlockTokenEnabled())
391        .setKeyUpdateInterval(keys.getKeyUpdateInterval())
392        .setTokenLifeTime(keys.getTokenLifetime())
393        .setCurrentKey(convert(keys.getCurrentKey()));
394    for (BlockKey k : keys.getAllKeys()) {
395      builder.addAllKeys(convert(k));
396    }
397    return builder.build();
398  }
399
400  public static ExportedBlockKeys convert(ExportedBlockKeysProto keys) {
401    return new ExportedBlockKeys(keys.getIsBlockTokenEnabled(),
402        keys.getKeyUpdateInterval(), keys.getTokenLifeTime(),
403        convert(keys.getCurrentKey()), convertBlockKeys(keys.getAllKeysList()));
404  }
405
406  public static CheckpointSignatureProto convert(CheckpointSignature s) {
407    return CheckpointSignatureProto.newBuilder()
408        .setBlockPoolId(s.getBlockpoolID())
409        .setCurSegmentTxId(s.getCurSegmentTxId())
410        .setMostRecentCheckpointTxId(s.getMostRecentCheckpointTxId())
411        .setStorageInfo(PBHelper.convert((StorageInfo) s)).build();
412  }
413
414  public static CheckpointSignature convert(CheckpointSignatureProto s) {
415    StorageInfo si = PBHelper.convert(s.getStorageInfo(), NodeType.NAME_NODE);
416    return new CheckpointSignature(si, s.getBlockPoolId(),
417        s.getMostRecentCheckpointTxId(), s.getCurSegmentTxId());
418  }
419
420  public static RemoteEditLogProto convert(RemoteEditLog log) {
421    return RemoteEditLogProto.newBuilder()
422        .setStartTxId(log.getStartTxId())
423        .setEndTxId(log.getEndTxId())
424        .setIsInProgress(log.isInProgress()).build();
425  }
426
427  public static RemoteEditLog convert(RemoteEditLogProto l) {
428    return new RemoteEditLog(l.getStartTxId(), l.getEndTxId(),
429        l.getIsInProgress());
430  }
431
432  public static RemoteEditLogManifestProto convert(
433      RemoteEditLogManifest manifest) {
434    RemoteEditLogManifestProto.Builder builder = RemoteEditLogManifestProto
435        .newBuilder();
436    for (RemoteEditLog log : manifest.getLogs()) {
437      builder.addLogs(convert(log));
438    }
439    return builder.build();
440  }
441
442  public static RemoteEditLogManifest convert(
443      RemoteEditLogManifestProto manifest) {
444    List<RemoteEditLog> logs = new ArrayList<RemoteEditLog>(manifest
445        .getLogsList().size());
446    for (RemoteEditLogProto l : manifest.getLogsList()) {
447      logs.add(convert(l));
448    }
449    return new RemoteEditLogManifest(logs);
450  }
451
452  public static CheckpointCommandProto convert(CheckpointCommand cmd) {
453    return CheckpointCommandProto.newBuilder()
454        .setSignature(convert(cmd.getSignature()))
455        .setNeedToReturnImage(cmd.needToReturnImage()).build();
456  }
457
458  public static NamenodeCommandProto convert(NamenodeCommand cmd) {
459    if (cmd instanceof CheckpointCommand) {
460      return NamenodeCommandProto.newBuilder().setAction(cmd.getAction())
461          .setType(NamenodeCommandProto.Type.CheckPointCommand)
462          .setCheckpointCmd(convert((CheckpointCommand) cmd)).build();
463    }
464    return NamenodeCommandProto.newBuilder()
465        .setType(NamenodeCommandProto.Type.NamenodeCommand)
466        .setAction(cmd.getAction()).build();
467  }
468
469  public static BlockKey[] convertBlockKeys(List<BlockKeyProto> list) {
470    BlockKey[] ret = new BlockKey[list.size()];
471    int i = 0;
472    for (BlockKeyProto k : list) {
473      ret[i++] = convert(k);
474    }
475    return ret;
476  }
477
478  public static NamespaceInfo convert(NamespaceInfoProto info) {
479    StorageInfoProto storage = info.getStorageInfo();
480    return new NamespaceInfo(storage.getNamespceID(), storage.getClusterID(),
481        info.getBlockPoolID(), storage.getCTime(), info.getBuildVersion(),
482        info.getSoftwareVersion());
483  }
484
485  public static NamenodeCommand convert(NamenodeCommandProto cmd) {
486    if (cmd == null) return null;
487    switch (cmd.getType()) {
488    case CheckPointCommand:
489      CheckpointCommandProto chkPt = cmd.getCheckpointCmd();
490      return new CheckpointCommand(PBHelper.convert(chkPt.getSignature()),
491          chkPt.getNeedToReturnImage());
492    default:
493      return new NamenodeCommand(cmd.getAction());
494    }
495  }
496  
497  public static ExtendedBlock convert(ExtendedBlockProto eb) {
498    if (eb == null) return null;
499    return new ExtendedBlock( eb.getPoolId(),  eb.getBlockId(),   eb.getNumBytes(),
500       eb.getGenerationStamp());
501  }
502  
503  public static ExtendedBlockProto convert(final ExtendedBlock b) {
504    if (b == null) return null;
505   return ExtendedBlockProto.newBuilder().
506      setPoolId(b.getBlockPoolId()).
507      setBlockId(b.getBlockId()).
508      setNumBytes(b.getNumBytes()).
509      setGenerationStamp(b.getGenerationStamp()).
510      build();
511  }
512  
513  public static RecoveringBlockProto convert(RecoveringBlock b) {
514    if (b == null) {
515      return null;
516    }
517    LocatedBlockProto lb = PBHelper.convert((LocatedBlock)b);
518    return RecoveringBlockProto.newBuilder().setBlock(lb)
519        .setNewGenStamp(b.getNewGenerationStamp()).build();
520  }
521
522  public static RecoveringBlock convert(RecoveringBlockProto b) {
523    ExtendedBlock block = convert(b.getBlock().getB());
524    DatanodeInfo[] locs = convert(b.getBlock().getLocsList());
525    return new RecoveringBlock(block, locs, b.getNewGenStamp());
526  }
527  
528  public static DatanodeInfoProto.AdminState convert(
529      final DatanodeInfo.AdminStates inAs) {
530    switch (inAs) {
531    case NORMAL: return  DatanodeInfoProto.AdminState.NORMAL;
532    case DECOMMISSION_INPROGRESS: 
533        return DatanodeInfoProto.AdminState.DECOMMISSION_INPROGRESS;
534    case DECOMMISSIONED: return DatanodeInfoProto.AdminState.DECOMMISSIONED;
535    default: return DatanodeInfoProto.AdminState.NORMAL;
536    }
537  }
538  
539  static public DatanodeInfo convert(DatanodeInfoProto di) {
540    if (di == null) return null;
541    return new DatanodeInfo(
542        PBHelper.convert(di.getId()),
543        di.hasLocation() ? di.getLocation() : null , 
544        di.getCapacity(),  di.getDfsUsed(),  di.getRemaining(),
545        di.getBlockPoolUsed(), di.getCacheCapacity(), di.getCacheUsed(),
546        di.getLastUpdate(), di.getXceiverCount(),
547        PBHelper.convert(di.getAdminState())); 
548  }
549  
550  static public DatanodeInfoProto convertDatanodeInfo(DatanodeInfo di) {
551    if (di == null) return null;
552    return convert(di);
553  }
554  
555  
556  static public DatanodeInfo[] convert(DatanodeInfoProto di[]) {
557    if (di == null) return null;
558    DatanodeInfo[] result = new DatanodeInfo[di.length];
559    for (int i = 0; i < di.length; i++) {
560      result[i] = convert(di[i]);
561    }    
562    return result;
563  }
564
565  public static List<? extends HdfsProtos.DatanodeInfoProto> convert(
566      DatanodeInfo[] dnInfos) {
567    return convert(dnInfos, 0);
568  }
569  
570  /**
571   * Copy from {@code dnInfos} to a target of list of same size starting at
572   * {@code startIdx}.
573   */
574  public static List<? extends HdfsProtos.DatanodeInfoProto> convert(
575      DatanodeInfo[] dnInfos, int startIdx) {
576    if (dnInfos == null)
577      return null;
578    ArrayList<HdfsProtos.DatanodeInfoProto> protos = Lists
579        .newArrayListWithCapacity(dnInfos.length);
580    for (int i = startIdx; i < dnInfos.length; i++) {
581      protos.add(convert(dnInfos[i]));
582    }
583    return protos;
584  }
585
586  public static DatanodeInfo[] convert(List<DatanodeInfoProto> list) {
587    DatanodeInfo[] info = new DatanodeInfo[list.size()];
588    for (int i = 0; i < info.length; i++) {
589      info[i] = convert(list.get(i));
590    }
591    return info;
592  }
593  
594  public static DatanodeInfoProto convert(DatanodeInfo info) {
595    DatanodeInfoProto.Builder builder = DatanodeInfoProto.newBuilder();
596    if (info.getNetworkLocation() != null) {
597      builder.setLocation(info.getNetworkLocation());
598    }
599    builder
600        .setId(PBHelper.convert((DatanodeID)info))
601        .setCapacity(info.getCapacity())
602        .setDfsUsed(info.getDfsUsed())
603        .setRemaining(info.getRemaining())
604        .setBlockPoolUsed(info.getBlockPoolUsed())
605        .setCacheCapacity(info.getCacheCapacity())
606        .setCacheUsed(info.getCacheUsed())
607        .setLastUpdate(info.getLastUpdate())
608        .setXceiverCount(info.getXceiverCount())
609        .setAdminState(PBHelper.convert(info.getAdminState()))
610        .build();
611    return builder.build();
612  }
613
614  public static AdminStates convert(AdminState adminState) {
615    switch(adminState) {
616    case DECOMMISSION_INPROGRESS:
617      return AdminStates.DECOMMISSION_INPROGRESS;
618    case DECOMMISSIONED:
619      return AdminStates.DECOMMISSIONED;
620    case NORMAL:
621    default:
622      return AdminStates.NORMAL;
623    }
624  }
625  
626  public static LocatedBlockProto convert(LocatedBlock b) {
627    if (b == null) return null;
628    Builder builder = LocatedBlockProto.newBuilder();
629    DatanodeInfo[] locs = b.getLocations();
630    List<DatanodeInfo> cachedLocs =
631        Lists.newLinkedList(Arrays.asList(b.getCachedLocations()));
632    for (int i = 0; i < locs.length; i++) {
633      DatanodeInfo loc = locs[i];
634      builder.addLocs(i, PBHelper.convert(loc));
635      boolean locIsCached = cachedLocs.contains(loc);
636      builder.addIsCached(locIsCached);
637      if (locIsCached) {
638        cachedLocs.remove(loc);
639      }
640    }
641    Preconditions.checkArgument(cachedLocs.size() == 0,
642        "Found additional cached replica locations that are not in the set of"
643        + " storage-backed locations!");
644
645    StorageType[] storageTypes = b.getStorageTypes();
646    if (storageTypes != null) {
647      for (int i = 0; i < storageTypes.length; ++i) {
648        builder.addStorageTypes(PBHelper.convertStorageType(storageTypes[i]));
649      }
650    }
651    final String[] storageIDs = b.getStorageIDs();
652    if (storageIDs != null) {
653      builder.addAllStorageIDs(Arrays.asList(storageIDs));
654    }
655
656    return builder.setB(PBHelper.convert(b.getBlock()))
657        .setBlockToken(PBHelper.convert(b.getBlockToken()))
658        .setCorrupt(b.isCorrupt()).setOffset(b.getStartOffset()).build();
659  }
660  
661  public static LocatedBlock convert(LocatedBlockProto proto) {
662    if (proto == null) return null;
663    List<DatanodeInfoProto> locs = proto.getLocsList();
664    DatanodeInfo[] targets = new DatanodeInfo[locs.size()];
665    for (int i = 0; i < locs.size(); i++) {
666      targets[i] = PBHelper.convert(locs.get(i));
667    }
668
669    final int storageTypesCount = proto.getStorageTypesCount();
670    final StorageType[] storageTypes;
671    if (storageTypesCount == 0) {
672      storageTypes = null;
673    } else {
674      Preconditions.checkState(storageTypesCount == locs.size());
675      storageTypes = convertStorageTypeProtos(proto.getStorageTypesList());
676    }
677
678    final int storageIDsCount = proto.getStorageIDsCount();
679    final String[] storageIDs;
680    if (storageIDsCount == 0) {
681      storageIDs = null;
682    } else {
683      Preconditions.checkState(storageIDsCount == locs.size());
684      storageIDs = proto.getStorageIDsList().toArray(new String[storageIDsCount]);
685    }
686
687    // Set values from the isCached list, re-using references from loc
688    List<DatanodeInfo> cachedLocs = new ArrayList<DatanodeInfo>(locs.size());
689    List<Boolean> isCachedList = proto.getIsCachedList();
690    for (int i=0; i<isCachedList.size(); i++) {
691      if (isCachedList.get(i)) {
692        cachedLocs.add(targets[i]);
693      }
694    }
695
696    LocatedBlock lb = new LocatedBlock(PBHelper.convert(proto.getB()), targets,
697        storageIDs, storageTypes, proto.getOffset(), proto.getCorrupt(),
698        cachedLocs.toArray(new DatanodeInfo[0]));
699    lb.setBlockToken(PBHelper.convert(proto.getBlockToken()));
700
701    return lb;
702  }
703
704  public static TokenProto convert(Token<?> tok) {
705    return TokenProto.newBuilder().
706              setIdentifier(ByteString.copyFrom(tok.getIdentifier())).
707              setPassword(ByteString.copyFrom(tok.getPassword())).
708              setKind(tok.getKind().toString()).
709              setService(tok.getService().toString()).build(); 
710  }
711  
712  public static Token<BlockTokenIdentifier> convert(
713      TokenProto blockToken) {
714    return new Token<BlockTokenIdentifier>(blockToken.getIdentifier()
715        .toByteArray(), blockToken.getPassword().toByteArray(), new Text(
716        blockToken.getKind()), new Text(blockToken.getService()));
717  }
718
719  
720  public static Token<DelegationTokenIdentifier> convertDelegationToken(
721      TokenProto blockToken) {
722    return new Token<DelegationTokenIdentifier>(blockToken.getIdentifier()
723        .toByteArray(), blockToken.getPassword().toByteArray(), new Text(
724        blockToken.getKind()), new Text(blockToken.getService()));
725  }
726
727  public static ReplicaState convert(ReplicaStateProto state) {
728    switch (state) {
729    case RBW:
730      return ReplicaState.RBW;
731    case RUR:
732      return ReplicaState.RUR;
733    case RWR:
734      return ReplicaState.RWR;
735    case TEMPORARY:
736      return ReplicaState.TEMPORARY;
737    case FINALIZED:
738    default:
739      return ReplicaState.FINALIZED;
740    }
741  }
742
743  public static ReplicaStateProto convert(ReplicaState state) {
744    switch (state) {
745    case RBW:
746      return ReplicaStateProto.RBW;
747    case RUR:
748      return ReplicaStateProto.RUR;
749    case RWR:
750      return ReplicaStateProto.RWR;
751    case TEMPORARY:
752      return ReplicaStateProto.TEMPORARY;
753    case FINALIZED:
754    default:
755      return ReplicaStateProto.FINALIZED;
756    }
757  }
758  
759  public static DatanodeRegistrationProto convert(
760      DatanodeRegistration registration) {
761    DatanodeRegistrationProto.Builder builder = DatanodeRegistrationProto
762        .newBuilder();
763    return builder.setDatanodeID(PBHelper.convert((DatanodeID) registration))
764        .setStorageInfo(PBHelper.convert(registration.getStorageInfo()))
765        .setKeys(PBHelper.convert(registration.getExportedKeys()))
766        .setSoftwareVersion(registration.getSoftwareVersion()).build();
767  }
768
769  public static DatanodeRegistration convert(DatanodeRegistrationProto proto) {
770    StorageInfo si = convert(proto.getStorageInfo(), NodeType.DATA_NODE);
771    return new DatanodeRegistration(PBHelper.convert(proto.getDatanodeID()),
772        si, PBHelper.convert(proto.getKeys()), proto.getSoftwareVersion());
773  }
774
775  public static DatanodeCommand convert(DatanodeCommandProto proto) {
776    switch (proto.getCmdType()) {
777    case BalancerBandwidthCommand:
778      return PBHelper.convert(proto.getBalancerCmd());
779    case BlockCommand:
780      return PBHelper.convert(proto.getBlkCmd());
781    case BlockRecoveryCommand:
782      return PBHelper.convert(proto.getRecoveryCmd());
783    case FinalizeCommand:
784      return PBHelper.convert(proto.getFinalizeCmd());
785    case KeyUpdateCommand:
786      return PBHelper.convert(proto.getKeyUpdateCmd());
787    case RegisterCommand:
788      return REG_CMD;
789    case BlockIdCommand:
790      return PBHelper.convert(proto.getBlkIdCmd());
791    default:
792      return null;
793    }
794  }
795  
796  public static BalancerBandwidthCommandProto convert(
797      BalancerBandwidthCommand bbCmd) {
798    return BalancerBandwidthCommandProto.newBuilder()
799        .setBandwidth(bbCmd.getBalancerBandwidthValue()).build();
800  }
801
802  public static KeyUpdateCommandProto convert(KeyUpdateCommand cmd) {
803    return KeyUpdateCommandProto.newBuilder()
804        .setKeys(PBHelper.convert(cmd.getExportedKeys())).build();
805  }
806
807  public static BlockRecoveryCommandProto convert(BlockRecoveryCommand cmd) {
808    BlockRecoveryCommandProto.Builder builder = BlockRecoveryCommandProto
809        .newBuilder();
810    for (RecoveringBlock b : cmd.getRecoveringBlocks()) {
811      builder.addBlocks(PBHelper.convert(b));
812    }
813    return builder.build();
814  }
815
816  public static FinalizeCommandProto convert(FinalizeCommand cmd) {
817    return FinalizeCommandProto.newBuilder()
818        .setBlockPoolId(cmd.getBlockPoolId()).build();
819  }
820
821  public static BlockCommandProto convert(BlockCommand cmd) {
822    BlockCommandProto.Builder builder = BlockCommandProto.newBuilder()
823        .setBlockPoolId(cmd.getBlockPoolId());
824    switch (cmd.getAction()) {
825    case DatanodeProtocol.DNA_TRANSFER:
826      builder.setAction(BlockCommandProto.Action.TRANSFER);
827      break;
828    case DatanodeProtocol.DNA_INVALIDATE:
829      builder.setAction(BlockCommandProto.Action.INVALIDATE);
830      break;
831    case DatanodeProtocol.DNA_SHUTDOWN:
832      builder.setAction(BlockCommandProto.Action.SHUTDOWN);
833      break;
834    default:
835      throw new AssertionError("Invalid action");
836    }
837    Block[] blocks = cmd.getBlocks();
838    for (int i = 0; i < blocks.length; i++) {
839      builder.addBlocks(PBHelper.convert(blocks[i]));
840    }
841    builder.addAllTargets(convert(cmd.getTargets()))
842           .addAllTargetStorageUuids(convert(cmd.getTargetStorageIDs()));
843    return builder.build();
844  }
845  
846  public static BlockIdCommandProto convert(BlockIdCommand cmd) {
847    BlockIdCommandProto.Builder builder = BlockIdCommandProto.newBuilder()
848        .setBlockPoolId(cmd.getBlockPoolId());
849    switch (cmd.getAction()) {
850    case DatanodeProtocol.DNA_CACHE:
851      builder.setAction(BlockIdCommandProto.Action.CACHE);
852      break;
853    case DatanodeProtocol.DNA_UNCACHE:
854      builder.setAction(BlockIdCommandProto.Action.UNCACHE);
855      break;
856    default:
857      throw new AssertionError("Invalid action");
858    }
859    long[] blockIds = cmd.getBlockIds();
860    for (int i = 0; i < blockIds.length; i++) {
861      builder.addBlockIds(blockIds[i]);
862    }
863    return builder.build();
864  }
865
866  private static List<DatanodeInfosProto> convert(DatanodeInfo[][] targets) {
867    DatanodeInfosProto[] ret = new DatanodeInfosProto[targets.length];
868    for (int i = 0; i < targets.length; i++) {
869      ret[i] = DatanodeInfosProto.newBuilder()
870          .addAllDatanodes(PBHelper.convert(targets[i])).build();
871    }
872    return Arrays.asList(ret);
873  }
874
875  private static List<StorageUuidsProto> convert(String[][] targetStorageUuids) {
876    StorageUuidsProto[] ret = new StorageUuidsProto[targetStorageUuids.length];
877    for (int i = 0; i < targetStorageUuids.length; i++) {
878      ret[i] = StorageUuidsProto.newBuilder()
879          .addAllStorageUuids(Arrays.asList(targetStorageUuids[i])).build();
880    }
881    return Arrays.asList(ret);
882  }
883
884  public static DatanodeCommandProto convert(DatanodeCommand datanodeCommand) {
885    DatanodeCommandProto.Builder builder = DatanodeCommandProto.newBuilder();
886    if (datanodeCommand == null) {
887      return builder.setCmdType(DatanodeCommandProto.Type.NullDatanodeCommand)
888          .build();
889    }
890    switch (datanodeCommand.getAction()) {
891    case DatanodeProtocol.DNA_BALANCERBANDWIDTHUPDATE:
892      builder.setCmdType(DatanodeCommandProto.Type.BalancerBandwidthCommand)
893          .setBalancerCmd(
894              PBHelper.convert((BalancerBandwidthCommand) datanodeCommand));
895      break;
896    case DatanodeProtocol.DNA_ACCESSKEYUPDATE:
897      builder
898          .setCmdType(DatanodeCommandProto.Type.KeyUpdateCommand)
899          .setKeyUpdateCmd(PBHelper.convert((KeyUpdateCommand) datanodeCommand));
900      break;
901    case DatanodeProtocol.DNA_RECOVERBLOCK:
902      builder.setCmdType(DatanodeCommandProto.Type.BlockRecoveryCommand)
903          .setRecoveryCmd(
904              PBHelper.convert((BlockRecoveryCommand) datanodeCommand));
905      break;
906    case DatanodeProtocol.DNA_FINALIZE:
907      builder.setCmdType(DatanodeCommandProto.Type.FinalizeCommand)
908          .setFinalizeCmd(PBHelper.convert((FinalizeCommand) datanodeCommand));
909      break;
910    case DatanodeProtocol.DNA_REGISTER:
911      builder.setCmdType(DatanodeCommandProto.Type.RegisterCommand)
912          .setRegisterCmd(REG_CMD_PROTO);
913      break;
914    case DatanodeProtocol.DNA_TRANSFER:
915    case DatanodeProtocol.DNA_INVALIDATE:
916    case DatanodeProtocol.DNA_SHUTDOWN:
917      builder.setCmdType(DatanodeCommandProto.Type.BlockCommand).
918        setBlkCmd(PBHelper.convert((BlockCommand) datanodeCommand));
919      break;
920    case DatanodeProtocol.DNA_CACHE:
921    case DatanodeProtocol.DNA_UNCACHE:
922      builder.setCmdType(DatanodeCommandProto.Type.BlockIdCommand).
923        setBlkIdCmd(PBHelper.convert((BlockIdCommand) datanodeCommand));
924      break;
925    case DatanodeProtocol.DNA_UNKNOWN: //Not expected
926    default:
927      builder.setCmdType(DatanodeCommandProto.Type.NullDatanodeCommand);
928    }
929    return builder.build();
930  }
931
932  public static KeyUpdateCommand convert(KeyUpdateCommandProto keyUpdateCmd) {
933    return new KeyUpdateCommand(PBHelper.convert(keyUpdateCmd.getKeys()));
934  }
935
936  public static FinalizeCommand convert(FinalizeCommandProto finalizeCmd) {
937    return new FinalizeCommand(finalizeCmd.getBlockPoolId());
938  }
939
940  public static BlockRecoveryCommand convert(
941      BlockRecoveryCommandProto recoveryCmd) {
942    List<RecoveringBlockProto> list = recoveryCmd.getBlocksList();
943    List<RecoveringBlock> recoveringBlocks = new ArrayList<RecoveringBlock>(
944        list.size());
945    
946    for (RecoveringBlockProto rbp : list) {
947      recoveringBlocks.add(PBHelper.convert(rbp));
948    }
949    return new BlockRecoveryCommand(recoveringBlocks);
950  }
951
952  public static BlockCommand convert(BlockCommandProto blkCmd) {
953    List<BlockProto> blockProtoList = blkCmd.getBlocksList();
954    Block[] blocks = new Block[blockProtoList.size()];
955    for (int i = 0; i < blockProtoList.size(); i++) {
956      blocks[i] = PBHelper.convert(blockProtoList.get(i));
957    }
958    List<DatanodeInfosProto> targetList = blkCmd.getTargetsList();
959    DatanodeInfo[][] targets = new DatanodeInfo[targetList.size()][];
960    for (int i = 0; i < targetList.size(); i++) {
961      targets[i] = PBHelper.convert(targetList.get(i));
962    }
963
964    List<StorageUuidsProto> targetStorageUuidsList = blkCmd.getTargetStorageUuidsList();
965    String[][] targetStorageIDs = new String[targetStorageUuidsList.size()][];
966    for(int i = 0; i < targetStorageIDs.length; i++) {
967      List<String> storageIDs = targetStorageUuidsList.get(i).getStorageUuidsList();
968      targetStorageIDs[i] = storageIDs.toArray(new String[storageIDs.size()]);
969    }
970
971    int action = DatanodeProtocol.DNA_UNKNOWN;
972    switch (blkCmd.getAction()) {
973    case TRANSFER:
974      action = DatanodeProtocol.DNA_TRANSFER;
975      break;
976    case INVALIDATE:
977      action = DatanodeProtocol.DNA_INVALIDATE;
978      break;
979    case SHUTDOWN:
980      action = DatanodeProtocol.DNA_SHUTDOWN;
981      break;
982    default:
983      throw new AssertionError("Unknown action type: " + blkCmd.getAction());
984    }
985    return new BlockCommand(action, blkCmd.getBlockPoolId(), blocks, targets,
986        targetStorageIDs);
987  }
988
989  public static BlockIdCommand convert(BlockIdCommandProto blkIdCmd) {
990    int numBlockIds = blkIdCmd.getBlockIdsCount();
991    long blockIds[] = new long[numBlockIds];
992    for (int i = 0; i < numBlockIds; i++) {
993      blockIds[i] = blkIdCmd.getBlockIds(i);
994    }
995    int action = DatanodeProtocol.DNA_UNKNOWN;
996    switch (blkIdCmd.getAction()) {
997    case CACHE:
998      action = DatanodeProtocol.DNA_CACHE;
999      break;
1000    case UNCACHE:
1001      action = DatanodeProtocol.DNA_UNCACHE;
1002      break;
1003    default:
1004      throw new AssertionError("Unknown action type: " + blkIdCmd.getAction());
1005    }
1006    return new BlockIdCommand(action, blkIdCmd.getBlockPoolId(), blockIds);
1007  }
1008
1009  public static DatanodeInfo[] convert(DatanodeInfosProto datanodeInfosProto) {
1010    List<DatanodeInfoProto> proto = datanodeInfosProto.getDatanodesList();
1011    DatanodeInfo[] infos = new DatanodeInfo[proto.size()];
1012    for (int i = 0; i < infos.length; i++) {
1013      infos[i] = PBHelper.convert(proto.get(i));
1014    }
1015    return infos;
1016  }
1017
1018  public static BalancerBandwidthCommand convert(
1019      BalancerBandwidthCommandProto balancerCmd) {
1020    return new BalancerBandwidthCommand(balancerCmd.getBandwidth());
1021  }
1022
1023  public static ReceivedDeletedBlockInfoProto convert(
1024      ReceivedDeletedBlockInfo receivedDeletedBlockInfo) {
1025    ReceivedDeletedBlockInfoProto.Builder builder = 
1026        ReceivedDeletedBlockInfoProto.newBuilder();
1027    
1028    ReceivedDeletedBlockInfoProto.BlockStatus status;
1029    switch (receivedDeletedBlockInfo.getStatus()) {
1030    case RECEIVING_BLOCK:
1031      status = ReceivedDeletedBlockInfoProto.BlockStatus.RECEIVING;
1032      break;
1033    case RECEIVED_BLOCK:
1034      status = ReceivedDeletedBlockInfoProto.BlockStatus.RECEIVED;
1035      break;
1036    case DELETED_BLOCK:
1037      status = ReceivedDeletedBlockInfoProto.BlockStatus.DELETED;
1038      break;
1039    default:
1040      throw new IllegalArgumentException("Bad status: " +
1041          receivedDeletedBlockInfo.getStatus());
1042    }
1043    builder.setStatus(status);
1044    
1045    if (receivedDeletedBlockInfo.getDelHints() != null) {
1046      builder.setDeleteHint(receivedDeletedBlockInfo.getDelHints());
1047    }
1048    return builder.setBlock(PBHelper.convert(receivedDeletedBlockInfo.getBlock()))
1049        .build();
1050  }
1051
1052  public static ReceivedDeletedBlockInfo convert(
1053      ReceivedDeletedBlockInfoProto proto) {
1054    ReceivedDeletedBlockInfo.BlockStatus status = null;
1055    switch (proto.getStatus()) {
1056    case RECEIVING:
1057      status = BlockStatus.RECEIVING_BLOCK;
1058      break;
1059    case RECEIVED:
1060      status = BlockStatus.RECEIVED_BLOCK;
1061      break;
1062    case DELETED:
1063      status = BlockStatus.DELETED_BLOCK;
1064      break;
1065    }
1066    return new ReceivedDeletedBlockInfo(
1067        PBHelper.convert(proto.getBlock()),
1068        status,
1069        proto.hasDeleteHint() ? proto.getDeleteHint() : null);
1070  }
1071  
1072  public static NamespaceInfoProto convert(NamespaceInfo info) {
1073    return NamespaceInfoProto.newBuilder()
1074        .setBlockPoolID(info.getBlockPoolID())
1075        .setBuildVersion(info.getBuildVersion())
1076        .setUnused(0)
1077        .setStorageInfo(PBHelper.convert((StorageInfo)info))
1078        .setSoftwareVersion(info.getSoftwareVersion()).build();
1079  }
1080  
1081  // Located Block Arrays and Lists
1082  public static LocatedBlockProto[] convertLocatedBlock(LocatedBlock[] lb) {
1083    if (lb == null) return null;
1084    return convertLocatedBlock2(Arrays.asList(lb)).toArray(
1085        new LocatedBlockProto[lb.length]);
1086  }
1087  
1088  public static LocatedBlock[] convertLocatedBlock(LocatedBlockProto[] lb) {
1089    if (lb == null) return null;
1090    return convertLocatedBlock(Arrays.asList(lb)).toArray(
1091        new LocatedBlock[lb.length]);
1092  }
1093  
1094  public static List<LocatedBlock> convertLocatedBlock(
1095      List<LocatedBlockProto> lb) {
1096    if (lb == null) return null;
1097    final int len = lb.size();
1098    List<LocatedBlock> result = 
1099        new ArrayList<LocatedBlock>(len);
1100    for (int i = 0; i < len; ++i) {
1101      result.add(PBHelper.convert(lb.get(i)));
1102    }
1103    return result;
1104  }
1105  
1106  public static List<LocatedBlockProto> convertLocatedBlock2(List<LocatedBlock> lb) {
1107    if (lb == null) return null;
1108    final int len = lb.size();
1109    List<LocatedBlockProto> result = new ArrayList<LocatedBlockProto>(len);
1110    for (int i = 0; i < len; ++i) {
1111      result.add(PBHelper.convert(lb.get(i)));
1112    }
1113    return result;
1114  }
1115  
1116  
1117  // LocatedBlocks
1118  public static LocatedBlocks convert(LocatedBlocksProto lb) {
1119    return new LocatedBlocks(
1120        lb.getFileLength(), lb.getUnderConstruction(),
1121        PBHelper.convertLocatedBlock(lb.getBlocksList()),
1122        lb.hasLastBlock() ? PBHelper.convert(lb.getLastBlock()) : null,
1123        lb.getIsLastBlockComplete());
1124  }
1125  
1126  public static LocatedBlocksProto convert(LocatedBlocks lb) {
1127    if (lb == null) {
1128      return null;
1129    }
1130    LocatedBlocksProto.Builder builder = 
1131        LocatedBlocksProto.newBuilder();
1132    if (lb.getLastLocatedBlock() != null) {
1133      builder.setLastBlock(PBHelper.convert(lb.getLastLocatedBlock()));
1134    }
1135    return builder.setFileLength(lb.getFileLength())
1136        .setUnderConstruction(lb.isUnderConstruction())
1137        .addAllBlocks(PBHelper.convertLocatedBlock2(lb.getLocatedBlocks()))
1138        .setIsLastBlockComplete(lb.isLastBlockComplete()).build();
1139  }
1140  
1141  // DataEncryptionKey
1142  public static DataEncryptionKey convert(DataEncryptionKeyProto bet) {
1143    String encryptionAlgorithm = bet.getEncryptionAlgorithm();
1144    return new DataEncryptionKey(bet.getKeyId(),
1145        bet.getBlockPoolId(),
1146        bet.getNonce().toByteArray(),
1147        bet.getEncryptionKey().toByteArray(),
1148        bet.getExpiryDate(),
1149        encryptionAlgorithm.isEmpty() ? null : encryptionAlgorithm);
1150  }
1151  
1152  public static DataEncryptionKeyProto convert(DataEncryptionKey bet) {
1153    DataEncryptionKeyProto.Builder b = DataEncryptionKeyProto.newBuilder()
1154        .setKeyId(bet.keyId)
1155        .setBlockPoolId(bet.blockPoolId)
1156        .setNonce(ByteString.copyFrom(bet.nonce))
1157        .setEncryptionKey(ByteString.copyFrom(bet.encryptionKey))
1158        .setExpiryDate(bet.expiryDate);
1159    if (bet.encryptionAlgorithm != null) {
1160      b.setEncryptionAlgorithm(bet.encryptionAlgorithm);
1161    }
1162    return b.build();
1163  }
1164  
1165  public static FsServerDefaults convert(FsServerDefaultsProto fs) {
1166    if (fs == null) return null;
1167    return new FsServerDefaults(
1168        fs.getBlockSize(), fs.getBytesPerChecksum(), 
1169        fs.getWritePacketSize(), (short) fs.getReplication(),
1170        fs.getFileBufferSize(),
1171        fs.getEncryptDataTransfer(),
1172        fs.getTrashInterval(),
1173        PBHelper.convert(fs.getChecksumType()));
1174  }
1175  
1176  public static FsServerDefaultsProto convert(FsServerDefaults fs) {
1177    if (fs == null) return null;
1178    return FsServerDefaultsProto.newBuilder().
1179      setBlockSize(fs.getBlockSize()).
1180      setBytesPerChecksum(fs.getBytesPerChecksum()).
1181      setWritePacketSize(fs.getWritePacketSize())
1182      .setReplication(fs.getReplication())
1183      .setFileBufferSize(fs.getFileBufferSize())
1184      .setEncryptDataTransfer(fs.getEncryptDataTransfer())
1185      .setTrashInterval(fs.getTrashInterval())
1186      .setChecksumType(PBHelper.convert(fs.getChecksumType()))
1187      .build();
1188  }
1189  
1190  public static FsPermissionProto convert(FsPermission p) {
1191    return FsPermissionProto.newBuilder().setPerm(p.toExtendedShort()).build();
1192  }
1193  
1194  public static FsPermission convert(FsPermissionProto p) {
1195    return new FsAclPermission((short)p.getPerm());
1196  }
1197  
1198  
1199  // The creatFlag field in PB is a bitmask whose values are the same a the 
1200  // emum values of CreateFlag
1201  public static int convertCreateFlag(EnumSetWritable<CreateFlag> flag) {
1202    int value = 0;
1203    if (flag.contains(CreateFlag.APPEND)) {
1204      value |= CreateFlagProto.APPEND.getNumber();
1205    }
1206    if (flag.contains(CreateFlag.CREATE)) {
1207      value |= CreateFlagProto.CREATE.getNumber();
1208    }
1209    if (flag.contains(CreateFlag.OVERWRITE)) {
1210      value |= CreateFlagProto.OVERWRITE.getNumber();
1211    }
1212    return value;
1213  }
1214  
1215  public static EnumSetWritable<CreateFlag> convertCreateFlag(int flag) {
1216    EnumSet<CreateFlag> result = 
1217       EnumSet.noneOf(CreateFlag.class);   
1218    if ((flag & CreateFlagProto.APPEND_VALUE) == CreateFlagProto.APPEND_VALUE) {
1219      result.add(CreateFlag.APPEND);
1220    }
1221    if ((flag & CreateFlagProto.CREATE_VALUE) == CreateFlagProto.CREATE_VALUE) {
1222      result.add(CreateFlag.CREATE);
1223    }
1224    if ((flag & CreateFlagProto.OVERWRITE_VALUE) 
1225        == CreateFlagProto.OVERWRITE_VALUE) {
1226      result.add(CreateFlag.OVERWRITE);
1227    }
1228    return new EnumSetWritable<CreateFlag>(result);
1229  }
1230
1231  public static int convertCacheFlags(EnumSet<CacheFlag> flags) {
1232    int value = 0;
1233    if (flags.contains(CacheFlag.FORCE)) {
1234      value |= CacheFlagProto.FORCE.getNumber();
1235    }
1236    return value;
1237  }
1238
1239  public static EnumSet<CacheFlag> convertCacheFlags(int flags) {
1240    EnumSet<CacheFlag> result = EnumSet.noneOf(CacheFlag.class);
1241    if ((flags & CacheFlagProto.FORCE_VALUE) == CacheFlagProto.FORCE_VALUE) {
1242      result.add(CacheFlag.FORCE);
1243    }
1244    return result;
1245  }
1246
1247  public static HdfsFileStatus convert(HdfsFileStatusProto fs) {
1248    if (fs == null)
1249      return null;
1250    return new HdfsLocatedFileStatus(
1251        fs.getLength(), fs.getFileType().equals(FileType.IS_DIR), 
1252        fs.getBlockReplication(), fs.getBlocksize(),
1253        fs.getModificationTime(), fs.getAccessTime(),
1254        PBHelper.convert(fs.getPermission()), fs.getOwner(), fs.getGroup(), 
1255        fs.getFileType().equals(FileType.IS_SYMLINK) ? 
1256            fs.getSymlink().toByteArray() : null,
1257        fs.getPath().toByteArray(),
1258        fs.hasFileId()? fs.getFileId(): INodeId.GRANDFATHER_INODE_ID,
1259        fs.hasLocations() ? PBHelper.convert(fs.getLocations()) : null,
1260        fs.hasChildrenNum() ? fs.getChildrenNum() : -1);
1261  }
1262
1263  public static SnapshottableDirectoryStatus convert(
1264      SnapshottableDirectoryStatusProto sdirStatusProto) {
1265    if (sdirStatusProto == null) {
1266      return null;
1267    }
1268    final HdfsFileStatusProto status = sdirStatusProto.getDirStatus();
1269    return new SnapshottableDirectoryStatus(
1270        status.getModificationTime(),
1271        status.getAccessTime(),
1272        PBHelper.convert(status.getPermission()),
1273        status.getOwner(),
1274        status.getGroup(),
1275        status.getPath().toByteArray(),
1276        status.getFileId(),
1277        status.getChildrenNum(),
1278        sdirStatusProto.getSnapshotNumber(),
1279        sdirStatusProto.getSnapshotQuota(),
1280        sdirStatusProto.getParentFullpath().toByteArray());
1281  }
1282  
1283  public static HdfsFileStatusProto convert(HdfsFileStatus fs) {
1284    if (fs == null)
1285      return null;
1286    FileType fType = FileType.IS_FILE;
1287    if (fs.isDir()) {
1288      fType = FileType.IS_DIR;
1289    } else if (fs.isSymlink()) {
1290      fType = FileType.IS_SYMLINK;
1291    }
1292
1293    HdfsFileStatusProto.Builder builder = 
1294     HdfsFileStatusProto.newBuilder().
1295      setLength(fs.getLen()).
1296      setFileType(fType).
1297      setBlockReplication(fs.getReplication()).
1298      setBlocksize(fs.getBlockSize()).
1299      setModificationTime(fs.getModificationTime()).
1300      setAccessTime(fs.getAccessTime()).
1301      setPermission(PBHelper.convert(fs.getPermission())).
1302      setOwner(fs.getOwner()).
1303      setGroup(fs.getGroup()).
1304      setFileId(fs.getFileId()).
1305      setChildrenNum(fs.getChildrenNum()).
1306      setPath(ByteString.copyFrom(fs.getLocalNameInBytes()));
1307    if (fs.isSymlink())  {
1308      builder.setSymlink(ByteString.copyFrom(fs.getSymlinkInBytes()));
1309    }
1310    if (fs instanceof HdfsLocatedFileStatus) {
1311      LocatedBlocks locations = ((HdfsLocatedFileStatus)fs).getBlockLocations();
1312      if (locations != null) {
1313        builder.setLocations(PBHelper.convert(locations));
1314      }
1315    }
1316    return builder.build();
1317  }
1318  
1319  public static SnapshottableDirectoryStatusProto convert(
1320      SnapshottableDirectoryStatus status) {
1321    if (status == null) {
1322      return null;
1323    }
1324    int snapshotNumber = status.getSnapshotNumber();
1325    int snapshotQuota = status.getSnapshotQuota();
1326    byte[] parentFullPath = status.getParentFullPath();
1327    ByteString parentFullPathBytes = ByteString.copyFrom(
1328        parentFullPath == null ? DFSUtil.EMPTY_BYTES : parentFullPath);
1329    HdfsFileStatusProto fs = convert(status.getDirStatus());
1330    SnapshottableDirectoryStatusProto.Builder builder = 
1331        SnapshottableDirectoryStatusProto
1332        .newBuilder().setSnapshotNumber(snapshotNumber)
1333        .setSnapshotQuota(snapshotQuota).setParentFullpath(parentFullPathBytes)
1334        .setDirStatus(fs);
1335    return builder.build();
1336  }
1337  
1338  public static HdfsFileStatusProto[] convert(HdfsFileStatus[] fs) {
1339    if (fs == null) return null;
1340    final int len = fs.length;
1341    HdfsFileStatusProto[] result = new HdfsFileStatusProto[len];
1342    for (int i = 0; i < len; ++i) {
1343      result[i] = PBHelper.convert(fs[i]);
1344    }
1345    return result;
1346  }
1347  
1348  public static HdfsFileStatus[] convert(HdfsFileStatusProto[] fs) {
1349    if (fs == null) return null;
1350    final int len = fs.length;
1351    HdfsFileStatus[] result = new HdfsFileStatus[len];
1352    for (int i = 0; i < len; ++i) {
1353      result[i] = PBHelper.convert(fs[i]);
1354    }
1355    return result;
1356  }
1357  
1358  public static DirectoryListing convert(DirectoryListingProto dl) {
1359    if (dl == null)
1360      return null;
1361    List<HdfsFileStatusProto> partList =  dl.getPartialListingList();
1362    return new DirectoryListing( 
1363        partList.isEmpty() ? new HdfsLocatedFileStatus[0] 
1364          : PBHelper.convert(
1365              partList.toArray(new HdfsFileStatusProto[partList.size()])),
1366        dl.getRemainingEntries());
1367  }
1368
1369  public static DirectoryListingProto convert(DirectoryListing d) {
1370    if (d == null)
1371      return null;
1372    return DirectoryListingProto.newBuilder().
1373        addAllPartialListing(Arrays.asList(
1374            PBHelper.convert(d.getPartialListing()))).
1375        setRemainingEntries(d.getRemainingEntries()).
1376        build();
1377  }
1378
1379  public static long[] convert(GetFsStatsResponseProto res) {
1380    long[] result = new long[6];
1381    result[ClientProtocol.GET_STATS_CAPACITY_IDX] = res.getCapacity();
1382    result[ClientProtocol.GET_STATS_USED_IDX] = res.getUsed();
1383    result[ClientProtocol.GET_STATS_REMAINING_IDX] = res.getRemaining();
1384    result[ClientProtocol.GET_STATS_UNDER_REPLICATED_IDX] = res.getUnderReplicated();
1385    result[ClientProtocol.GET_STATS_CORRUPT_BLOCKS_IDX] = res.getCorruptBlocks();
1386    result[ClientProtocol.GET_STATS_MISSING_BLOCKS_IDX] = res.getMissingBlocks();
1387    return result;
1388  }
1389  
1390  public static GetFsStatsResponseProto convert(long[] fsStats) {
1391    GetFsStatsResponseProto.Builder result = GetFsStatsResponseProto
1392        .newBuilder();
1393    if (fsStats.length >= ClientProtocol.GET_STATS_CAPACITY_IDX + 1)
1394      result.setCapacity(fsStats[ClientProtocol.GET_STATS_CAPACITY_IDX]);
1395    if (fsStats.length >= ClientProtocol.GET_STATS_USED_IDX + 1)
1396      result.setUsed(fsStats[ClientProtocol.GET_STATS_USED_IDX]);
1397    if (fsStats.length >= ClientProtocol.GET_STATS_REMAINING_IDX + 1)
1398      result.setRemaining(fsStats[ClientProtocol.GET_STATS_REMAINING_IDX]);
1399    if (fsStats.length >= ClientProtocol.GET_STATS_UNDER_REPLICATED_IDX + 1)
1400      result.setUnderReplicated(
1401              fsStats[ClientProtocol.GET_STATS_UNDER_REPLICATED_IDX]);
1402    if (fsStats.length >= ClientProtocol.GET_STATS_CORRUPT_BLOCKS_IDX + 1)
1403      result.setCorruptBlocks(
1404          fsStats[ClientProtocol.GET_STATS_CORRUPT_BLOCKS_IDX]);
1405    if (fsStats.length >= ClientProtocol.GET_STATS_MISSING_BLOCKS_IDX + 1)
1406      result.setMissingBlocks(
1407          fsStats[ClientProtocol.GET_STATS_MISSING_BLOCKS_IDX]);
1408    return result.build();
1409  }
1410  
1411  public static DatanodeReportTypeProto
1412    convert(DatanodeReportType t) {
1413    switch (t) {
1414    case ALL: return DatanodeReportTypeProto.ALL;
1415    case LIVE: return DatanodeReportTypeProto.LIVE;
1416    case DEAD: return DatanodeReportTypeProto.DEAD;
1417    default: 
1418      throw new IllegalArgumentException("Unexpected data type report:" + t);
1419    }
1420  }
1421  
1422  public static DatanodeReportType 
1423    convert(DatanodeReportTypeProto t) {
1424    switch (t) {
1425    case ALL: return DatanodeReportType.ALL;
1426    case LIVE: return DatanodeReportType.LIVE;
1427    case DEAD: return DatanodeReportType.DEAD;
1428    default: 
1429      throw new IllegalArgumentException("Unexpected data type report:" + t);
1430    }
1431  }
1432
1433  public static SafeModeActionProto convert(
1434      SafeModeAction a) {
1435    switch (a) {
1436    case SAFEMODE_LEAVE:
1437      return SafeModeActionProto.SAFEMODE_LEAVE;
1438    case SAFEMODE_ENTER:
1439      return SafeModeActionProto.SAFEMODE_ENTER;
1440    case SAFEMODE_GET:
1441      return SafeModeActionProto.SAFEMODE_GET;
1442    default:
1443      throw new IllegalArgumentException("Unexpected SafeModeAction :" + a);
1444    }
1445  }
1446  
1447  public static SafeModeAction convert(
1448      ClientNamenodeProtocolProtos.SafeModeActionProto a) {
1449    switch (a) {
1450    case SAFEMODE_LEAVE:
1451      return SafeModeAction.SAFEMODE_LEAVE;
1452    case SAFEMODE_ENTER:
1453      return SafeModeAction.SAFEMODE_ENTER;
1454    case SAFEMODE_GET:
1455      return SafeModeAction.SAFEMODE_GET;
1456    default:
1457      throw new IllegalArgumentException("Unexpected SafeModeAction :" + a);
1458    }
1459  }
1460  
1461  public static RollingUpgradeActionProto convert(RollingUpgradeAction a) {
1462    switch (a) {
1463    case QUERY:
1464      return RollingUpgradeActionProto.QUERY;
1465    case PREPARE:
1466      return RollingUpgradeActionProto.START;
1467    case FINALIZE:
1468      return RollingUpgradeActionProto.FINALIZE;
1469    default:
1470      throw new IllegalArgumentException("Unexpected value: " + a);
1471    }
1472  }
1473  
1474  public static RollingUpgradeAction convert(RollingUpgradeActionProto a) {
1475    switch (a) {
1476    case QUERY:
1477      return RollingUpgradeAction.QUERY;
1478    case START:
1479      return RollingUpgradeAction.PREPARE;
1480    case FINALIZE:
1481      return RollingUpgradeAction.FINALIZE;
1482    default:
1483      throw new IllegalArgumentException("Unexpected value: " + a);
1484    }
1485  }
1486
1487  public static RollingUpgradeStatusProto convertRollingUpgradeStatus(
1488      RollingUpgradeStatus status) {
1489    return RollingUpgradeStatusProto.newBuilder()
1490        .setBlockPoolId(status.getBlockPoolId())
1491        .build();
1492  }
1493
1494  public static RollingUpgradeStatus convert(RollingUpgradeStatusProto proto) {
1495    return new RollingUpgradeStatus(proto.getBlockPoolId());
1496  }
1497
1498  public static RollingUpgradeInfoProto convert(RollingUpgradeInfo info) {
1499    return RollingUpgradeInfoProto.newBuilder()
1500        .setStatus(convertRollingUpgradeStatus(info))
1501        .setCreatedRollbackImages(info.createdRollbackImages())
1502        .setStartTime(info.getStartTime())
1503        .setFinalizeTime(info.getFinalizeTime())
1504        .build();
1505  }
1506
1507  public static RollingUpgradeInfo convert(RollingUpgradeInfoProto proto) {
1508    RollingUpgradeStatusProto status = proto.getStatus();
1509    return new RollingUpgradeInfo(status.getBlockPoolId(),
1510        proto.getCreatedRollbackImages(),
1511        proto.getStartTime(), proto.getFinalizeTime());
1512  }
1513
1514  public static CorruptFileBlocks convert(CorruptFileBlocksProto c) {
1515    if (c == null)
1516      return null;
1517    List<String> fileList = c.getFilesList();
1518    return new CorruptFileBlocks(fileList.toArray(new String[fileList.size()]),
1519        c.getCookie());
1520  }
1521
1522  public static CorruptFileBlocksProto convert(CorruptFileBlocks c) {
1523    if (c == null)
1524      return null;
1525    return CorruptFileBlocksProto.newBuilder().
1526        addAllFiles(Arrays.asList(c.getFiles())).
1527        setCookie(c.getCookie()).
1528        build();
1529  }
1530  
1531  public static ContentSummary convert(ContentSummaryProto cs) {
1532    if (cs == null) return null;
1533    return new ContentSummary(
1534      cs.getLength(), cs.getFileCount(), cs.getDirectoryCount(), cs.getQuota(),
1535      cs.getSpaceConsumed(), cs.getSpaceQuota());
1536  }
1537  
1538  public static ContentSummaryProto convert(ContentSummary cs) {
1539    if (cs == null) return null;
1540    return ContentSummaryProto.newBuilder().
1541        setLength(cs.getLength()).
1542        setFileCount(cs.getFileCount()).
1543        setDirectoryCount(cs.getDirectoryCount()).
1544        setQuota(cs.getQuota()).
1545        setSpaceConsumed(cs.getSpaceConsumed()).
1546        setSpaceQuota(cs.getSpaceQuota()).
1547        build();
1548  }
1549
1550  public static NNHAStatusHeartbeat convert(NNHAStatusHeartbeatProto s) {
1551    if (s == null) return null;
1552    switch (s.getState()) {
1553    case ACTIVE:
1554      return new NNHAStatusHeartbeat(HAServiceState.ACTIVE, s.getTxid());
1555    case STANDBY:
1556      return new NNHAStatusHeartbeat(HAServiceState.STANDBY, s.getTxid());
1557    default:
1558      throw new IllegalArgumentException("Unexpected NNHAStatusHeartbeat.State:" + s.getState());
1559    }
1560  }
1561
1562  public static NNHAStatusHeartbeatProto convert(NNHAStatusHeartbeat hb) {
1563    if (hb == null) return null;
1564    NNHAStatusHeartbeatProto.Builder builder =
1565      NNHAStatusHeartbeatProto.newBuilder();
1566    switch (hb.getState()) {
1567      case ACTIVE:
1568        builder.setState(NNHAStatusHeartbeatProto.State.ACTIVE);
1569        break;
1570      case STANDBY:
1571        builder.setState(NNHAStatusHeartbeatProto.State.STANDBY);
1572        break;
1573      default:
1574        throw new IllegalArgumentException("Unexpected NNHAStatusHeartbeat.State:" +
1575            hb.getState());
1576    }
1577    builder.setTxid(hb.getTxId());
1578    return builder.build();
1579  }
1580
1581  public static DatanodeStorageProto convert(DatanodeStorage s) {
1582    return DatanodeStorageProto.newBuilder()
1583        .setState(PBHelper.convertState(s.getState()))
1584        .setStorageType(PBHelper.convertStorageType(s.getStorageType()))
1585        .setStorageUuid(s.getStorageID()).build();
1586  }
1587
1588  private static StorageState convertState(State state) {
1589    switch(state) {
1590    case READ_ONLY_SHARED:
1591      return StorageState.READ_ONLY_SHARED;
1592    case NORMAL:
1593    default:
1594      return StorageState.NORMAL;
1595    }
1596  }
1597
1598  private static StorageTypeProto convertStorageType(
1599      StorageType type) {
1600    switch(type) {
1601    case DISK:
1602      return StorageTypeProto.DISK;
1603    case SSD:
1604      return StorageTypeProto.SSD;
1605    default:
1606      throw new IllegalStateException(
1607          "BUG: StorageType not found, type=" + type);
1608    }
1609  }
1610
1611  public static DatanodeStorage convert(DatanodeStorageProto s) {
1612    return new DatanodeStorage(s.getStorageUuid(),
1613                               PBHelper.convertState(s.getState()),
1614                               PBHelper.convertType(s.getStorageType()));
1615  }
1616
1617  private static State convertState(StorageState state) {
1618    switch(state) {
1619    case READ_ONLY_SHARED:
1620      return DatanodeStorage.State.READ_ONLY_SHARED;
1621    case NORMAL:
1622    default:
1623      return DatanodeStorage.State.NORMAL;
1624    }
1625  }
1626
1627  private static StorageType convertType(StorageTypeProto type) {
1628    switch(type) {
1629      case DISK:
1630        return StorageType.DISK;
1631      case SSD:
1632        return StorageType.SSD;
1633      default:
1634        throw new IllegalStateException(
1635            "BUG: StorageTypeProto not found, type=" + type);
1636    }
1637  }
1638
1639  private static StorageType[] convertStorageTypeProtos(
1640      List<StorageTypeProto> storageTypesList) {
1641    final StorageType[] storageTypes = new StorageType[storageTypesList.size()];
1642    for (int i = 0; i < storageTypes.length; ++i) {
1643      storageTypes[i] = PBHelper.convertType(storageTypesList.get(i));
1644    }
1645    return storageTypes;
1646  }
1647
1648  public static StorageReportProto convert(StorageReport r) {
1649    StorageReportProto.Builder builder = StorageReportProto.newBuilder()
1650        .setBlockPoolUsed(r.getBlockPoolUsed()).setCapacity(r.getCapacity())
1651        .setDfsUsed(r.getDfsUsed()).setRemaining(r.getRemaining())
1652        .setStorageUuid(r.getStorage().getStorageID())
1653        .setStorage(convert(r.getStorage()));
1654    return builder.build();
1655  }
1656
1657  public static StorageReport convert(StorageReportProto p) {
1658    return new StorageReport(
1659        p.hasStorage() ?
1660            convert(p.getStorage()) :
1661            new DatanodeStorage(p.getStorageUuid()),
1662        p.getFailed(), p.getCapacity(), p.getDfsUsed(), p.getRemaining(),
1663        p.getBlockPoolUsed());
1664  }
1665
1666  public static StorageReport[] convertStorageReports(
1667      List<StorageReportProto> list) {
1668    final StorageReport[] report = new StorageReport[list.size()];
1669    for (int i = 0; i < report.length; i++) {
1670      report[i] = convert(list.get(i));
1671    }
1672    return report;
1673  }
1674
1675  public static JournalInfo convert(JournalInfoProto info) {
1676    int lv = info.hasLayoutVersion() ? info.getLayoutVersion() : 0;
1677    int nsID = info.hasNamespaceID() ? info.getNamespaceID() : 0;
1678    return new JournalInfo(lv, info.getClusterID(), nsID);
1679  }
1680
1681  /**
1682   * Method used for converting {@link JournalInfoProto} sent from Namenode
1683   * to Journal receivers to {@link NamenodeRegistration}.
1684   */
1685  public static JournalInfoProto convert(JournalInfo j) {
1686    return JournalInfoProto.newBuilder().setClusterID(j.getClusterId())
1687        .setLayoutVersion(j.getLayoutVersion())
1688        .setNamespaceID(j.getNamespaceId()).build();
1689  } 
1690  
1691  public static SnapshottableDirectoryStatus[] convert(
1692      SnapshottableDirectoryListingProto sdlp) {
1693    if (sdlp == null)
1694      return null;
1695    List<SnapshottableDirectoryStatusProto> list = sdlp
1696        .getSnapshottableDirListingList();
1697    if (list.isEmpty()) {
1698      return new SnapshottableDirectoryStatus[0];
1699    } else {
1700      SnapshottableDirectoryStatus[] result = 
1701          new SnapshottableDirectoryStatus[list.size()];
1702      for (int i = 0; i < list.size(); i++) {
1703        result[i] = PBHelper.convert(list.get(i));
1704      }
1705      return result;
1706    }
1707  }
1708  
1709  public static SnapshottableDirectoryListingProto convert(
1710      SnapshottableDirectoryStatus[] status) {
1711    if (status == null)
1712      return null;
1713    SnapshottableDirectoryStatusProto[] protos = 
1714        new SnapshottableDirectoryStatusProto[status.length];
1715    for (int i = 0; i < status.length; i++) {
1716      protos[i] = PBHelper.convert(status[i]);
1717    }
1718    List<SnapshottableDirectoryStatusProto> protoList = Arrays.asList(protos);
1719    return SnapshottableDirectoryListingProto.newBuilder()
1720        .addAllSnapshottableDirListing(protoList).build();
1721  }
1722  
1723  public static DiffReportEntry convert(SnapshotDiffReportEntryProto entry) {
1724    if (entry == null) {
1725      return null;
1726    }
1727    DiffType type = DiffType.getTypeFromLabel(entry
1728        .getModificationLabel());
1729    return type == null ? null : 
1730      new DiffReportEntry(type, entry.getFullpath().toByteArray());
1731  }
1732  
1733  public static SnapshotDiffReportEntryProto convert(DiffReportEntry entry) {
1734    if (entry == null) {
1735      return null;
1736    }
1737    byte[] fullPath = entry.getRelativePath();
1738    ByteString fullPathString = ByteString
1739        .copyFrom(fullPath == null ? DFSUtil.EMPTY_BYTES : fullPath);
1740    
1741    String modification = entry.getType().getLabel();
1742    
1743    SnapshotDiffReportEntryProto entryProto = SnapshotDiffReportEntryProto
1744        .newBuilder().setFullpath(fullPathString)
1745        .setModificationLabel(modification).build();
1746    return entryProto;
1747  }
1748  
1749  public static SnapshotDiffReport convert(SnapshotDiffReportProto reportProto) {
1750    if (reportProto == null) {
1751      return null;
1752    }
1753    String snapshotDir = reportProto.getSnapshotRoot();
1754    String fromSnapshot = reportProto.getFromSnapshot();
1755    String toSnapshot = reportProto.getToSnapshot();
1756    List<SnapshotDiffReportEntryProto> list = reportProto
1757        .getDiffReportEntriesList();
1758    List<DiffReportEntry> entries = new ArrayList<DiffReportEntry>();
1759    for (SnapshotDiffReportEntryProto entryProto : list) {
1760      DiffReportEntry entry = convert(entryProto);
1761      if (entry != null)
1762        entries.add(entry);
1763    }
1764    return new SnapshotDiffReport(snapshotDir, fromSnapshot, toSnapshot,
1765        entries);
1766  }
1767  
1768  public static SnapshotDiffReportProto convert(SnapshotDiffReport report) {
1769    if (report == null) {
1770      return null;
1771    }
1772    List<DiffReportEntry> entries = report.getDiffList();
1773    List<SnapshotDiffReportEntryProto> entryProtos = 
1774        new ArrayList<SnapshotDiffReportEntryProto>();
1775    for (DiffReportEntry entry : entries) {
1776      SnapshotDiffReportEntryProto entryProto = convert(entry);
1777      if (entryProto != null)
1778        entryProtos.add(entryProto);
1779    }
1780    
1781    SnapshotDiffReportProto reportProto = SnapshotDiffReportProto.newBuilder()
1782        .setSnapshotRoot(report.getSnapshotRoot())
1783        .setFromSnapshot(report.getFromSnapshot())
1784        .setToSnapshot(report.getLaterSnapshotName())
1785        .addAllDiffReportEntries(entryProtos).build();
1786    return reportProto;
1787  }
1788
1789  public static DataChecksum.Type convert(HdfsProtos.ChecksumTypeProto type) {
1790    return DataChecksum.Type.valueOf(type.getNumber());
1791  }
1792
1793  public static CacheDirectiveInfoProto convert
1794      (CacheDirectiveInfo info) {
1795    CacheDirectiveInfoProto.Builder builder = 
1796        CacheDirectiveInfoProto.newBuilder();
1797    if (info.getId() != null) {
1798      builder.setId(info.getId());
1799    }
1800    if (info.getPath() != null) {
1801      builder.setPath(info.getPath().toUri().getPath());
1802    }
1803    if (info.getReplication() != null) {
1804      builder.setReplication(info.getReplication());
1805    }
1806    if (info.getPool() != null) {
1807      builder.setPool(info.getPool());
1808    }
1809    if (info.getExpiration() != null) {
1810      builder.setExpiration(convert(info.getExpiration()));
1811    }
1812    return builder.build();
1813  }
1814
1815  public static CacheDirectiveInfo convert
1816      (CacheDirectiveInfoProto proto) {
1817    CacheDirectiveInfo.Builder builder =
1818        new CacheDirectiveInfo.Builder();
1819    if (proto.hasId()) {
1820      builder.setId(proto.getId());
1821    }
1822    if (proto.hasPath()) {
1823      builder.setPath(new Path(proto.getPath()));
1824    }
1825    if (proto.hasReplication()) {
1826      builder.setReplication(Shorts.checkedCast(
1827          proto.getReplication()));
1828    }
1829    if (proto.hasPool()) {
1830      builder.setPool(proto.getPool());
1831    }
1832    if (proto.hasExpiration()) {
1833      builder.setExpiration(convert(proto.getExpiration()));
1834    }
1835    return builder.build();
1836  }
1837
1838  public static CacheDirectiveInfoExpirationProto convert(
1839      CacheDirectiveInfo.Expiration expiration) {
1840    return CacheDirectiveInfoExpirationProto.newBuilder()
1841        .setIsRelative(expiration.isRelative())
1842        .setMillis(expiration.getMillis())
1843        .build();
1844  }
1845
1846  public static CacheDirectiveInfo.Expiration convert(
1847      CacheDirectiveInfoExpirationProto proto) {
1848    if (proto.getIsRelative()) {
1849      return CacheDirectiveInfo.Expiration.newRelative(proto.getMillis());
1850    }
1851    return CacheDirectiveInfo.Expiration.newAbsolute(proto.getMillis());
1852  }
1853
1854  public static CacheDirectiveStatsProto convert(CacheDirectiveStats stats) {
1855    CacheDirectiveStatsProto.Builder builder = 
1856        CacheDirectiveStatsProto.newBuilder();
1857    builder.setBytesNeeded(stats.getBytesNeeded());
1858    builder.setBytesCached(stats.getBytesCached());
1859    builder.setFilesNeeded(stats.getFilesNeeded());
1860    builder.setFilesCached(stats.getFilesCached());
1861    builder.setHasExpired(stats.hasExpired());
1862    return builder.build();
1863  }
1864  
1865  public static CacheDirectiveStats convert(CacheDirectiveStatsProto proto) {
1866    CacheDirectiveStats.Builder builder = new CacheDirectiveStats.Builder();
1867    builder.setBytesNeeded(proto.getBytesNeeded());
1868    builder.setBytesCached(proto.getBytesCached());
1869    builder.setFilesNeeded(proto.getFilesNeeded());
1870    builder.setFilesCached(proto.getFilesCached());
1871    builder.setHasExpired(proto.getHasExpired());
1872    return builder.build();
1873  }
1874
1875  public static CacheDirectiveEntryProto convert(CacheDirectiveEntry entry) {
1876    CacheDirectiveEntryProto.Builder builder = 
1877        CacheDirectiveEntryProto.newBuilder();
1878    builder.setInfo(PBHelper.convert(entry.getInfo()));
1879    builder.setStats(PBHelper.convert(entry.getStats()));
1880    return builder.build();
1881  }
1882  
1883  public static CacheDirectiveEntry convert(CacheDirectiveEntryProto proto) {
1884    CacheDirectiveInfo info = PBHelper.convert(proto.getInfo());
1885    CacheDirectiveStats stats = PBHelper.convert(proto.getStats());
1886    return new CacheDirectiveEntry(info, stats);
1887  }
1888
1889  public static CachePoolInfoProto convert(CachePoolInfo info) {
1890    CachePoolInfoProto.Builder builder = CachePoolInfoProto.newBuilder();
1891    builder.setPoolName(info.getPoolName());
1892    if (info.getOwnerName() != null) {
1893      builder.setOwnerName(info.getOwnerName());
1894    }
1895    if (info.getGroupName() != null) {
1896      builder.setGroupName(info.getGroupName());
1897    }
1898    if (info.getMode() != null) {
1899      builder.setMode(info.getMode().toShort());
1900    }
1901    if (info.getLimit() != null) {
1902      builder.setLimit(info.getLimit());
1903    }
1904    if (info.getMaxRelativeExpiryMs() != null) {
1905      builder.setMaxRelativeExpiry(info.getMaxRelativeExpiryMs());
1906    }
1907    return builder.build();
1908  }
1909
1910  public static CachePoolInfo convert (CachePoolInfoProto proto) {
1911    // Pool name is a required field, the rest are optional
1912    String poolName = checkNotNull(proto.getPoolName());
1913    CachePoolInfo info = new CachePoolInfo(poolName);
1914    if (proto.hasOwnerName()) {
1915        info.setOwnerName(proto.getOwnerName());
1916    }
1917    if (proto.hasGroupName()) {
1918      info.setGroupName(proto.getGroupName());
1919    }
1920    if (proto.hasMode()) {
1921      info.setMode(new FsPermission((short)proto.getMode()));
1922    }
1923    if (proto.hasLimit())  {
1924      info.setLimit(proto.getLimit());
1925    }
1926    if (proto.hasMaxRelativeExpiry()) {
1927      info.setMaxRelativeExpiryMs(proto.getMaxRelativeExpiry());
1928    }
1929    return info;
1930  }
1931
1932  public static CachePoolStatsProto convert(CachePoolStats stats) {
1933    CachePoolStatsProto.Builder builder = CachePoolStatsProto.newBuilder();
1934    builder.setBytesNeeded(stats.getBytesNeeded());
1935    builder.setBytesCached(stats.getBytesCached());
1936    builder.setBytesOverlimit(stats.getBytesOverlimit());
1937    builder.setFilesNeeded(stats.getFilesNeeded());
1938    builder.setFilesCached(stats.getFilesCached());
1939    return builder.build();
1940  }
1941
1942  public static CachePoolStats convert (CachePoolStatsProto proto) {
1943    CachePoolStats.Builder builder = new CachePoolStats.Builder();
1944    builder.setBytesNeeded(proto.getBytesNeeded());
1945    builder.setBytesCached(proto.getBytesCached());
1946    builder.setBytesOverlimit(proto.getBytesOverlimit());
1947    builder.setFilesNeeded(proto.getFilesNeeded());
1948    builder.setFilesCached(proto.getFilesCached());
1949    return builder.build();
1950  }
1951
1952  public static CachePoolEntryProto convert(CachePoolEntry entry) {
1953    CachePoolEntryProto.Builder builder = CachePoolEntryProto.newBuilder();
1954    builder.setInfo(PBHelper.convert(entry.getInfo()));
1955    builder.setStats(PBHelper.convert(entry.getStats()));
1956    return builder.build();
1957  }
1958
1959  public static CachePoolEntry convert (CachePoolEntryProto proto) {
1960    CachePoolInfo info = PBHelper.convert(proto.getInfo());
1961    CachePoolStats stats = PBHelper.convert(proto.getStats());
1962    return new CachePoolEntry(info, stats);
1963  }
1964  
1965  public static HdfsProtos.ChecksumTypeProto convert(DataChecksum.Type type) {
1966    return HdfsProtos.ChecksumTypeProto.valueOf(type.id);
1967  }
1968
1969  public static DatanodeLocalInfoProto convert(DatanodeLocalInfo info) {
1970    DatanodeLocalInfoProto.Builder builder = DatanodeLocalInfoProto.newBuilder();
1971    builder.setSoftwareVersion(info.getSoftwareVersion());
1972    builder.setConfigVersion(info.getConfigVersion());
1973    builder.setUptime(info.getUptime());
1974    return builder.build();
1975  }
1976
1977  public static DatanodeLocalInfo convert(DatanodeLocalInfoProto proto) {
1978    return new DatanodeLocalInfo(proto.getSoftwareVersion(),
1979        proto.getConfigVersion(), proto.getUptime());
1980  }
1981
1982  public static InputStream vintPrefixed(final InputStream input)
1983      throws IOException {
1984    final int firstByte = input.read();
1985    if (firstByte == -1) {
1986      throw new EOFException("Premature EOF: no length prefix available");
1987    }
1988
1989    int size = CodedInputStream.readRawVarint32(firstByte, input);
1990    assert size >= 0;
1991    return new ExactSizeInputStream(input, size);
1992  }
1993
1994  private static AclEntryScopeProto convert(AclEntryScope v) {
1995    return AclEntryScopeProto.valueOf(v.ordinal());
1996  }
1997
1998  private static AclEntryScope convert(AclEntryScopeProto v) {
1999    return castEnum(v, ACL_ENTRY_SCOPE_VALUES);
2000  }
2001
2002  private static AclEntryTypeProto convert(AclEntryType e) {
2003    return AclEntryTypeProto.valueOf(e.ordinal());
2004  }
2005
2006  private static AclEntryType convert(AclEntryTypeProto v) {
2007    return castEnum(v, ACL_ENTRY_TYPE_VALUES);
2008  }
2009
2010  private static FsActionProto convert(FsAction v) {
2011    return FsActionProto.valueOf(v != null ? v.ordinal() : 0);
2012  }
2013
2014  private static FsAction convert(FsActionProto v) {
2015    return castEnum(v, FSACTION_VALUES);
2016  }
2017
2018  public static List<AclEntryProto> convertAclEntryProto(
2019      List<AclEntry> aclSpec) {
2020    ArrayList<AclEntryProto> r = Lists.newArrayListWithCapacity(aclSpec.size());
2021    for (AclEntry e : aclSpec) {
2022      AclEntryProto.Builder builder = AclEntryProto.newBuilder();
2023      builder.setType(convert(e.getType()));
2024      builder.setScope(convert(e.getScope()));
2025      builder.setPermissions(convert(e.getPermission()));
2026      if (e.getName() != null) {
2027        builder.setName(e.getName());
2028      }
2029      r.add(builder.build());
2030    }
2031    return r;
2032  }
2033
2034  public static List<AclEntry> convertAclEntry(List<AclEntryProto> aclSpec) {
2035    ArrayList<AclEntry> r = Lists.newArrayListWithCapacity(aclSpec.size());
2036    for (AclEntryProto e : aclSpec) {
2037      AclEntry.Builder builder = new AclEntry.Builder();
2038      builder.setType(convert(e.getType()));
2039      builder.setScope(convert(e.getScope()));
2040      builder.setPermission(convert(e.getPermissions()));
2041      if (e.hasName()) {
2042        builder.setName(e.getName());
2043      }
2044      r.add(builder.build());
2045    }
2046    return r;
2047  }
2048
2049  public static AclStatus convert(GetAclStatusResponseProto e) {
2050    AclStatusProto r = e.getResult();
2051    return new AclStatus.Builder().owner(r.getOwner()).group(r.getGroup())
2052        .stickyBit(r.getSticky())
2053        .addEntries(convertAclEntry(r.getEntriesList())).build();
2054  }
2055
2056  public static GetAclStatusResponseProto convert(AclStatus e) {
2057    AclStatusProto r = AclStatusProto.newBuilder().setOwner(e.getOwner())
2058        .setGroup(e.getGroup()).setSticky(e.isStickyBit())
2059        .addAllEntries(convertAclEntryProto(e.getEntries())).build();
2060    return GetAclStatusResponseProto.newBuilder().setResult(r).build();
2061  }
2062
2063  public static ShortCircuitShmSlotProto convert(SlotId slotId) {
2064    return ShortCircuitShmSlotProto.newBuilder().
2065        setShmId(convert(slotId.getShmId())).
2066        setSlotIdx(slotId.getSlotIdx()).
2067        build();
2068  }
2069
2070  public static ShortCircuitShmIdProto convert(ShmId shmId) {
2071    return ShortCircuitShmIdProto.newBuilder().
2072        setHi(shmId.getHi()).
2073        setLo(shmId.getLo()).
2074        build();
2075
2076  }
2077
2078  public static SlotId convert(ShortCircuitShmSlotProto slotId) {
2079    return new SlotId(PBHelper.convert(slotId.getShmId()),
2080        slotId.getSlotIdx());
2081  }
2082
2083  public static ShmId convert(ShortCircuitShmIdProto shmId) {
2084    return new ShmId(shmId.getHi(), shmId.getLo());
2085  }
2086}
2087