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;
19 
20 import java.util.List;
21 
22 import org.apache.hadoop.classification.InterfaceAudience;
23 import org.apache.hadoop.classification.InterfaceStability;
24 
25 import com.google.common.base.Preconditions;
26 import com.google.common.collect.Lists;
27 
28 /**
29  * This class is used to specify the setup of namenodes when instantiating
30  * a MiniDFSCluster. It consists of a set of nameservices, each of which
31  * may have one or more namenodes (in the case of HA)
32  */
33 @InterfaceAudience.LimitedPrivate({"HBase", "HDFS", "Hive", "MapReduce", "Pig"})
34 @InterfaceStability.Unstable
35 public class MiniDFSNNTopology {
36   private final List<NSConf> nameservices = Lists.newArrayList();
37   private boolean federation;
38 
MiniDFSNNTopology()39   public MiniDFSNNTopology() {
40   }
41 
42   /**
43    * Set up a simple non-federated non-HA NN.
44    */
simpleSingleNN( int nameNodePort, int nameNodeHttpPort)45   public static MiniDFSNNTopology simpleSingleNN(
46       int nameNodePort, int nameNodeHttpPort) {
47     return new MiniDFSNNTopology()
48       .addNameservice(new MiniDFSNNTopology.NSConf(null)
49         .addNN(new MiniDFSNNTopology.NNConf(null)
50           .setHttpPort(nameNodeHttpPort)
51           .setIpcPort(nameNodePort)));
52   }
53 
54 
55   /**
56    * Set up an HA topology with a single HA nameservice.
57    */
simpleHATopology()58   public static MiniDFSNNTopology simpleHATopology() {
59     return new MiniDFSNNTopology()
60       .addNameservice(new MiniDFSNNTopology.NSConf("minidfs-ns")
61         .addNN(new MiniDFSNNTopology.NNConf("nn1"))
62         .addNN(new MiniDFSNNTopology.NNConf("nn2")));
63   }
64 
65   /**
66    * Set up federated cluster with the given number of nameservices, each
67    * of which has only a single NameNode.
68    */
simpleFederatedTopology( int numNameservices)69   public static MiniDFSNNTopology simpleFederatedTopology(
70       int numNameservices) {
71     MiniDFSNNTopology topology = new MiniDFSNNTopology();
72     for (int i = 1; i <= numNameservices; i++) {
73       topology.addNameservice(new MiniDFSNNTopology.NSConf("ns" + i)
74         .addNN(new MiniDFSNNTopology.NNConf(null)));
75     }
76     topology.setFederation(true);
77     return topology;
78   }
79 
80   /**
81    * Set up federated cluster with the given nameservices, each
82    * of which has only a single NameNode.
83    */
simpleFederatedTopology(String nameservicesIds)84   public static MiniDFSNNTopology simpleFederatedTopology(String nameservicesIds) {
85     MiniDFSNNTopology topology = new MiniDFSNNTopology();
86     String nsIds[] = nameservicesIds.split(",");
87     for (String nsId : nsIds) {
88       topology.addNameservice(new MiniDFSNNTopology.NSConf(nsId)
89         .addNN(new MiniDFSNNTopology.NNConf(null)));
90     }
91     topology.setFederation(true);
92     return topology;
93   }
94 
95   /**
96    * Set up federated cluster with the given number of nameservices, each
97    * of which has two NameNodes.
98    */
simpleHAFederatedTopology( int numNameservices)99   public static MiniDFSNNTopology simpleHAFederatedTopology(
100       int numNameservices) {
101     MiniDFSNNTopology topology = new MiniDFSNNTopology();
102     for (int i = 0; i < numNameservices; i++) {
103       topology.addNameservice(new MiniDFSNNTopology.NSConf("ns" + i)
104         .addNN(new MiniDFSNNTopology.NNConf("nn0"))
105         .addNN(new MiniDFSNNTopology.NNConf("nn1")));
106     }
107     topology.setFederation(true);
108     return topology;
109   }
110 
setFederation(boolean federation)111   public MiniDFSNNTopology setFederation(boolean federation) {
112     this.federation = federation;
113     return this;
114   }
115 
addNameservice(NSConf nameservice)116   public MiniDFSNNTopology addNameservice(NSConf nameservice) {
117     Preconditions.checkArgument(!nameservice.getNNs().isEmpty(),
118         "Must have at least one NN in a nameservice");
119     this.nameservices.add(nameservice);
120     return this;
121   }
122 
countNameNodes()123   public int countNameNodes() {
124     int count = 0;
125     for (NSConf ns : nameservices) {
126       count += ns.nns.size();
127     }
128     return count;
129   }
130 
getOnlyNameNode()131   public NNConf getOnlyNameNode() {
132     Preconditions.checkState(countNameNodes() == 1,
133         "must have exactly one NN!");
134     return nameservices.get(0).getNNs().get(0);
135   }
136 
isFederated()137   public boolean isFederated() {
138     return nameservices.size() > 1 || federation;
139   }
140 
141   /**
142    * @return true if at least one of the nameservices
143    * in the topology has HA enabled.
144    */
isHA()145   public boolean isHA() {
146     for (NSConf ns : nameservices) {
147       if (ns.getNNs().size() > 1) {
148         return true;
149       }
150     }
151     return false;
152   }
153 
154   /**
155    * @return true if all of the NNs in the cluster have their HTTP
156    * port specified to be non-ephemeral.
157    */
allHttpPortsSpecified()158   public boolean allHttpPortsSpecified() {
159     for (NSConf ns : nameservices) {
160       for (NNConf nn : ns.getNNs()) {
161         if (nn.getHttpPort() == 0) {
162           return false;
163         }
164       }
165     }
166     return true;
167   }
168 
169   /**
170    * @return true if all of the NNs in the cluster have their IPC
171    * port specified to be non-ephemeral.
172    */
allIpcPortsSpecified()173   public boolean allIpcPortsSpecified() {
174     for (NSConf ns : nameservices) {
175       for (NNConf nn : ns.getNNs()) {
176         if (nn.getIpcPort() == 0) {
177           return false;
178         }
179       }
180     }
181     return true;
182   }
183 
getNameservices()184   public List<NSConf> getNameservices() {
185     return nameservices;
186   }
187 
188   public static class NSConf {
189     private final String id;
190     private final List<NNConf> nns = Lists.newArrayList();
191 
NSConf(String id)192     public NSConf(String id) {
193       this.id = id;
194     }
195 
addNN(NNConf nn)196     public NSConf addNN(NNConf nn) {
197       this.nns.add(nn);
198       return this;
199     }
200 
getId()201     public String getId() {
202       return id;
203     }
204 
getNNs()205     public List<NNConf> getNNs() {
206       return nns;
207     }
208   }
209 
210   public static class NNConf {
211     private final String nnId;
212     private int httpPort;
213     private int ipcPort;
214     private String clusterId;
215 
NNConf(String nnId)216     public NNConf(String nnId) {
217       this.nnId = nnId;
218     }
219 
getNnId()220     String getNnId() {
221       return nnId;
222     }
223 
getIpcPort()224     int getIpcPort() {
225       return ipcPort;
226     }
227 
getHttpPort()228     int getHttpPort() {
229       return httpPort;
230     }
231 
getClusterId()232     String getClusterId() {
233       return clusterId;
234     }
235 
setHttpPort(int httpPort)236     public NNConf setHttpPort(int httpPort) {
237       this.httpPort = httpPort;
238       return this;
239     }
240 
setIpcPort(int ipcPort)241     public NNConf setIpcPort(int ipcPort) {
242       this.ipcPort = ipcPort;
243       return this;
244     }
245 
setClusterId(String clusterId)246     public NNConf setClusterId(String clusterId) {
247       this.clusterId = clusterId;
248       return this;
249     }
250   }
251 
252 }
253