1 /**
2  * Licensed to the Apache Software Foundation (ASF) under one
3  * or more contributor license agreements.  See the NOTICE file
4  * distributed with this work for additional information
5  * regarding copyright ownership.  The ASF licenses this file
6  * to you under the Apache License, Version 2.0 (the
7  * "License"); you may not use this file except in compliance
8  * with the License.  You may obtain a copy of the License at
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  */
18 package org.apache.hadoop.hdfs.server.namenode;
19 
20 import static org.mockito.Mockito.spy;
21 
22 import java.io.File;
23 import java.io.IOException;
24 import java.util.concurrent.locks.ReentrantReadWriteLock;
25 
26 import org.apache.hadoop.fs.UnresolvedLinkException;
27 import org.apache.hadoop.fs.permission.FsPermission;
28 import org.apache.hadoop.fs.permission.PermissionStatus;
29 import org.apache.hadoop.hdfs.DFSTestUtil;
30 import org.apache.hadoop.hdfs.protocol.DatanodeID;
31 import org.apache.hadoop.hdfs.protocol.HdfsFileStatus;
32 import org.apache.hadoop.hdfs.protocol.LocatedBlocks;
33 import org.apache.hadoop.hdfs.security.token.delegation.DelegationTokenSecretManager;
34 import org.apache.hadoop.hdfs.server.blockmanagement.BlockManagerTestUtil;
35 import org.apache.hadoop.hdfs.server.blockmanagement.DatanodeDescriptor;
36 import org.apache.hadoop.hdfs.server.common.Storage.StorageDirectory;
37 import org.apache.hadoop.hdfs.server.namenode.FSEditLogOp.MkdirOp;
38 import org.apache.hadoop.hdfs.server.namenode.FSNamesystem.SafeModeInfo;
39 import org.apache.hadoop.hdfs.server.namenode.LeaseManager.Lease;
40 import org.apache.hadoop.hdfs.server.namenode.ha.EditLogTailer;
41 import org.apache.hadoop.hdfs.server.protocol.DatanodeRegistration;
42 import org.apache.hadoop.hdfs.server.protocol.HeartbeatResponse;
43 import org.apache.hadoop.hdfs.server.protocol.NamenodeCommand;
44 import org.apache.hadoop.hdfs.server.protocol.NamenodeRegistration;
45 import org.apache.hadoop.ipc.Server;
46 import org.apache.hadoop.ipc.StandbyException;
47 import org.apache.hadoop.security.AccessControlException;
48 import org.mockito.Mockito;
49 import org.mockito.internal.util.reflection.Whitebox;
50 
51 /**
52  * This is a utility class to expose NameNode functionality for unit tests.
53  */
54 public class NameNodeAdapter {
55   /**
56    * Get the namesystem from the namenode
57    */
getNamesystem(NameNode namenode)58   public static FSNamesystem getNamesystem(NameNode namenode) {
59     return namenode.getNamesystem();
60   }
61 
62   /**
63    * Get block locations within the specified range.
64    */
getBlockLocations(NameNode namenode, String src, long offset, long length)65   public static LocatedBlocks getBlockLocations(NameNode namenode,
66       String src, long offset, long length) throws IOException {
67     return namenode.getNamesystem().getBlockLocations("foo",
68         src, offset, length);
69   }
70 
getFileInfo(NameNode namenode, String src, boolean resolveLink)71   public static HdfsFileStatus getFileInfo(NameNode namenode, String src,
72       boolean resolveLink) throws AccessControlException, UnresolvedLinkException,
73         StandbyException, IOException {
74     return FSDirStatAndListingOp.getFileInfo(namenode.getNamesystem()
75             .getFSDirectory(), src, resolveLink);
76   }
77 
mkdirs(NameNode namenode, String src, PermissionStatus permissions, boolean createParent)78   public static boolean mkdirs(NameNode namenode, String src,
79       PermissionStatus permissions, boolean createParent)
80       throws UnresolvedLinkException, IOException {
81     return namenode.getNamesystem().mkdirs(src, permissions, createParent);
82   }
83 
saveNamespace(NameNode namenode)84   public static void saveNamespace(NameNode namenode)
85       throws AccessControlException, IOException {
86     namenode.getNamesystem().saveNamespace();
87   }
88 
enterSafeMode(NameNode namenode, boolean resourcesLow)89   public static void enterSafeMode(NameNode namenode, boolean resourcesLow)
90       throws IOException {
91     namenode.getNamesystem().enterSafeMode(resourcesLow);
92   }
93 
leaveSafeMode(NameNode namenode)94   public static void leaveSafeMode(NameNode namenode) {
95     namenode.getNamesystem().leaveSafeMode();
96   }
97 
abortEditLogs(NameNode nn)98   public static void abortEditLogs(NameNode nn) {
99     FSEditLog el = nn.getFSImage().getEditLog();
100     el.abortCurrentLogSegment();
101   }
102 
103   /**
104    * Get the internal RPC server instance.
105    * @return rpc server
106    */
getRpcServer(NameNode namenode)107   public static Server getRpcServer(NameNode namenode) {
108     return ((NameNodeRpcServer)namenode.getRpcServer()).clientRpcServer;
109   }
110 
getDtSecretManager( final FSNamesystem ns)111   public static DelegationTokenSecretManager getDtSecretManager(
112       final FSNamesystem ns) {
113     return ns.getDelegationTokenSecretManager();
114   }
115 
sendHeartBeat(DatanodeRegistration nodeReg, DatanodeDescriptor dd, FSNamesystem namesystem)116   public static HeartbeatResponse sendHeartBeat(DatanodeRegistration nodeReg,
117       DatanodeDescriptor dd, FSNamesystem namesystem) throws IOException {
118     return namesystem.handleHeartbeat(nodeReg,
119         BlockManagerTestUtil.getStorageReportsForDatanode(dd),
120         dd.getCacheCapacity(), dd.getCacheRemaining(), 0, 0, 0, null);
121   }
122 
setReplication(final FSNamesystem ns, final String src, final short replication)123   public static boolean setReplication(final FSNamesystem ns,
124       final String src, final short replication) throws IOException {
125     return ns.setReplication(src, replication);
126   }
127 
getLeaseManager(final FSNamesystem ns)128   public static LeaseManager getLeaseManager(final FSNamesystem ns) {
129     return ns.leaseManager;
130   }
131 
132   /** Set the softLimit and hardLimit of client lease periods. */
setLeasePeriod(final FSNamesystem namesystem, long soft, long hard)133   public static void setLeasePeriod(final FSNamesystem namesystem, long soft, long hard) {
134     getLeaseManager(namesystem).setLeasePeriod(soft, hard);
135     namesystem.leaseManager.triggerMonitorCheckNow();
136   }
137 
getLeaseHolderForPath(NameNode namenode, String path)138   public static String getLeaseHolderForPath(NameNode namenode, String path) {
139     Lease l = namenode.getNamesystem().leaseManager.getLeaseByPath(path);
140     return l == null? null: l.getHolder();
141   }
142 
143   /**
144    * @return the timestamp of the last renewal of the given lease,
145    *   or -1 in the case that the lease doesn't exist.
146    */
getLeaseRenewalTime(NameNode nn, String path)147   public static long getLeaseRenewalTime(NameNode nn, String path) {
148     LeaseManager lm = nn.getNamesystem().leaseManager;
149     Lease l = lm.getLeaseByPath(path);
150     if (l == null) {
151       return -1;
152     }
153     return l.getLastUpdate();
154   }
155 
156   /**
157    * Return the datanode descriptor for the given datanode.
158    */
getDatanode(final FSNamesystem ns, DatanodeID id)159   public static DatanodeDescriptor getDatanode(final FSNamesystem ns,
160       DatanodeID id) throws IOException {
161     ns.readLock();
162     try {
163       return ns.getBlockManager().getDatanodeManager().getDatanode(id);
164     } finally {
165       ns.readUnlock();
166     }
167   }
168 
169   /**
170    * Return the FSNamesystem stats
171    */
getStats(final FSNamesystem fsn)172   public static long[] getStats(final FSNamesystem fsn) {
173     return fsn.getStats();
174   }
175 
spyOnFsLock(FSNamesystem fsn)176   public static ReentrantReadWriteLock spyOnFsLock(FSNamesystem fsn) {
177     ReentrantReadWriteLock spy = Mockito.spy(fsn.getFsLockForTests());
178     fsn.setFsLockForTests(spy);
179     return spy;
180   }
181 
spyOnFsImage(NameNode nn1)182   public static FSImage spyOnFsImage(NameNode nn1) {
183     FSNamesystem fsn = nn1.getNamesystem();
184     FSImage spy = Mockito.spy(fsn.getFSImage());
185     Whitebox.setInternalState(fsn, "fsImage", spy);
186     return spy;
187   }
188 
spyOnEditLog(NameNode nn)189   public static FSEditLog spyOnEditLog(NameNode nn) {
190     FSEditLog spyEditLog = spy(nn.getNamesystem().getFSImage().getEditLog());
191     DFSTestUtil.setEditLogForTesting(nn.getNamesystem(), spyEditLog);
192     EditLogTailer tailer = nn.getNamesystem().getEditLogTailer();
193     if (tailer != null) {
194       tailer.setEditLog(spyEditLog);
195     }
196     return spyEditLog;
197   }
198 
spyOnJournalSet(NameNode nn)199   public static JournalSet spyOnJournalSet(NameNode nn) {
200     FSEditLog editLog = nn.getFSImage().getEditLog();
201     JournalSet js = Mockito.spy(editLog.getJournalSet());
202     editLog.setJournalSetForTesting(js);
203     return js;
204   }
205 
getMkdirOpPath(FSEditLogOp op)206   public static String getMkdirOpPath(FSEditLogOp op) {
207     if (op.opCode == FSEditLogOpCodes.OP_MKDIR) {
208       return ((MkdirOp) op).path;
209     } else {
210       return null;
211     }
212   }
213 
createMkdirOp(String path)214   public static FSEditLogOp createMkdirOp(String path) {
215     MkdirOp op = MkdirOp.getInstance(new FSEditLogOp.OpInstanceCache())
216       .setPath(path)
217       .setTimestamp(0)
218       .setPermissionStatus(new PermissionStatus(
219               "testuser", "testgroup", FsPermission.getDefault()));
220     return op;
221   }
222 
223   /**
224    * @return the number of blocks marked safe by safemode, or -1
225    * if safemode is not running.
226    */
getSafeModeSafeBlocks(NameNode nn)227   public static int getSafeModeSafeBlocks(NameNode nn) {
228     SafeModeInfo smi = nn.getNamesystem().getSafeModeInfoForTests();
229     if (smi == null) {
230       return -1;
231     }
232     return smi.blockSafe;
233   }
234 
235   /**
236    * @return Replication queue initialization status
237    */
safeModeInitializedReplQueues(NameNode nn)238   public static boolean safeModeInitializedReplQueues(NameNode nn) {
239     return nn.getNamesystem().isPopulatingReplQueues();
240   }
241 
getInProgressEditsFile(StorageDirectory sd, long startTxId)242   public static File getInProgressEditsFile(StorageDirectory sd, long startTxId) {
243     return NNStorage.getInProgressEditsFile(sd, startTxId);
244   }
245 
startCheckpoint(NameNode nn, NamenodeRegistration backupNode, NamenodeRegistration activeNamenode)246   public static NamenodeCommand startCheckpoint(NameNode nn,
247       NamenodeRegistration backupNode, NamenodeRegistration activeNamenode)
248           throws IOException {
249     return nn.getNamesystem().startCheckpoint(backupNode, activeNamenode);
250   }
251 }
252 
253