Adding debug log messages for CoordinatorService - adding review comments
[voldemort/jeffpc.git] / src / java / voldemort / tools / admin / AdminUtils.java
blob495a63942a8d2e707b0becde88d7b7e162487809
1 /*
2 * Copyright 2008-2014 LinkedIn, Inc
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5 * use this file except in compliance with the License. You may obtain a copy of
6 * the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 * License for the specific language governing permissions and limitations under
14 * the License.
17 package voldemort.tools.admin;
19 import java.io.BufferedReader;
20 import java.io.File;
21 import java.io.IOException;
22 import java.io.InputStreamReader;
23 import java.util.ArrayList;
24 import java.util.Collection;
25 import java.util.HashMap;
26 import java.util.Iterator;
27 import java.util.List;
28 import java.util.Map;
29 import java.util.Set;
31 import voldemort.VoldemortException;
32 import voldemort.client.ClientConfig;
33 import voldemort.client.protocol.admin.AdminClient;
34 import voldemort.client.protocol.admin.AdminClientConfig;
35 import voldemort.cluster.Node;
36 import voldemort.store.StoreDefinition;
37 import voldemort.store.metadata.MetadataStore;
38 import voldemort.store.metadata.MetadataStore.VoldemortState;
39 import voldemort.store.quota.QuotaUtils;
40 import voldemort.store.system.SystemStoreConstants;
41 import voldemort.utils.Utils;
42 import voldemort.versioning.Versioned;
44 import com.google.common.collect.Lists;
45 import com.google.common.collect.Maps;
47 /**
48 * Utility class for AdminCommand
51 public class AdminUtils {
53 private static final String QUOTATYPE_ALL = "all";
55 /**
56 * Utility function that copies a string array except for the first element
58 * @param arr Original array of strings
59 * @return Copied array of strings
61 public static String[] copyArrayCutFirst(String[] arr) {
62 if(arr.length > 1) {
63 String[] arrCopy = new String[arr.length - 1];
64 System.arraycopy(arr, 1, arrCopy, 0, arrCopy.length);
65 return arrCopy;
66 } else {
67 return new String[0];
71 /**
72 * Utility function that copies a string array and add another string to
73 * first
75 * @param arr Original array of strings
76 * @param add
77 * @return Copied array of strings
79 public static String[] copyArrayAddFirst(String[] arr, String add) {
80 String[] arrCopy = new String[arr.length + 1];
81 arrCopy[0] = add;
82 System.arraycopy(arr, 0, arrCopy, 1, arr.length);
83 return arrCopy;
86 /**
87 * Utility function that pauses and asks for confirmation on dangerous
88 * operations.
90 * @param confirm User has already confirmed in command-line input
91 * @param opDesc Description of the dangerous operation
92 * @throws IOException
93 * @return True if user confirms the operation in either command-line input
94 * or here.
97 public static Boolean askConfirm(Boolean confirm, String opDesc) throws IOException {
98 if(confirm) {
99 System.out.println("Confirmed " + opDesc + " in command-line.");
100 return true;
101 } else {
102 System.out.println("Are you sure you want to " + opDesc + "? (yes/no)");
103 BufferedReader buffer = new BufferedReader(new InputStreamReader(System.in));
104 String text = buffer.readLine();
105 return text.equals("yes");
110 * Utility function that gives list of values from list of value-pair
111 * strings.
113 * @param valueList List of value-pair strings
114 * @param delim Delimiter that separates the value pair
115 * @returns The list of values; empty if no value-pair is present, The even
116 * elements are the first ones of the value pair, and the odd
117 * elements are the second ones. For example, if the list of
118 * value-pair is ["cluster.xml=file1", "stores.xml=file2"], and the
119 * pair delimiter is '=', we will then have the list of values in
120 * return: ["cluster.xml", "file1", "stores.xml", "file2"].
122 public static List<String> getValueList(List<String> valuePairs, String delim) {
123 List<String> valueList = Lists.newArrayList();
124 for(String valuePair: valuePairs) {
125 String[] value = valuePair.split(delim, 2);
126 if(value.length != 2)
127 throw new VoldemortException("Invalid argument pair: " + value);
128 valueList.add(value[0]);
129 valueList.add(value[1]);
131 return valueList;
135 * Utility function that converts a list to a map.
137 * @param list The list in which even elements are keys and odd elements are
138 * values.
139 * @rturn The map container that maps even elements to odd elements, e.g.
140 * 0->1, 2->3, etc.
142 public static <V> Map<V, V> convertListToMap(List<V> list) {
143 Map<V, V> map = new HashMap<V, V>();
144 if(list.size() % 2 != 0)
145 throw new VoldemortException("Failed to convert list to map.");
146 for(int i = 0; i < list.size(); i += 2) {
147 map.put(list.get(i), list.get(i + 1));
149 return map;
153 * Utility function that constructs AdminClient.
155 * @param url URL pointing to the bootstrap node
156 * @return Newly constructed AdminClient
158 public static AdminClient getAdminClient(String url) {
159 return new AdminClient(url, new AdminClientConfig(), new ClientConfig());
163 * Utility function that fetches nodes.
165 * @param adminClient An instance of AdminClient points to given cluster
166 * @param nodeIds List of node IDs parsed from command-line input
167 * @param allNodes Tells if all nodes are selected
168 * @return Collection of node objects selected by user
170 public static Collection<Node> getNodes(AdminClient adminClient,
171 List<Integer> nodeIds,
172 Boolean allNodes) {
173 Collection<Node> nodes = null;
174 if(allNodes) {
175 nodes = adminClient.getAdminClientCluster().getNodes();
176 } else {
177 nodes = new ArrayList<Node>();
178 for(Integer nodeId: nodeIds) {
179 nodes.add(adminClient.getAdminClientCluster().getNodeById(nodeId));
182 if(nodes.size() == 0) {
183 throw new VoldemortException("The cluster doesn't have any node.");
185 return nodes;
189 * Utility function that fetches stores on a node.
191 * @param adminClient An instance of AdminClient points to given cluster
192 * @param node Node to fetch stores from
193 * @param storeNames Stores read from command-line input
194 * @param allStores Tells if all stores are selected
195 * @return List of store names selected by user
197 public static List<String> getUserStoresOnNode(AdminClient adminClient,
198 Node node,
199 List<String> storeNames,
200 Boolean allStores) {
201 List<StoreDefinition> storeDefinitionList = adminClient.metadataMgmtOps.getRemoteStoreDefList(node.getId())
202 .getValue();
203 if(allStores) {
204 storeNames = Lists.newArrayList();
205 for(StoreDefinition storeDefinition: storeDefinitionList) {
206 storeNames.add(storeDefinition.getName());
208 } else {
209 for(String storeName: storeNames) {
210 if(!storeDefinitionList.contains(storeName))
211 Utils.croak("Store " + storeName + " does not exist!");
214 return storeNames;
218 * Utility function that fetches partitions.
220 * @param adminClient An instance of AdminClient points to given cluster
221 * @param partIds List of partitions read from command-line input
222 * @param allParts Tells if all partitions are selected
223 * @return List of partitions selected by user
225 public static List<Integer> getPartitions(AdminClient adminClient,
226 List<Integer> partIds,
227 Boolean allParts) {
228 if(allParts) {
229 partIds = Lists.newArrayList();
230 for(Node node: adminClient.getAdminClientCluster().getNodes()) {
231 partIds.addAll(node.getPartitionIds());
234 return partIds;
238 * Utility function that fetches quota types.
240 * @param nodeIds List of IDs of nodes parsed from command-line input
241 * @param allNodes Tells if all nodes are selected
242 * @return Collection of node objects selected by user
244 public static List<String> getQuotaTypes(List<String> quotaTypes) {
245 if(quotaTypes.size() < 1) {
246 throw new VoldemortException("Quota type not specified.");
248 Set<String> validQuotaTypes = QuotaUtils.validQuotaTypes();
249 if(quotaTypes.size() == 1 && quotaTypes.get(0).equals(AdminUtils.QUOTATYPE_ALL)) {
250 Iterator<String> iter = validQuotaTypes.iterator();
251 quotaTypes = Lists.newArrayList();
252 while(iter.hasNext()) {
253 quotaTypes.add(iter.next());
255 } else {
256 for(String quotaType: quotaTypes) {
257 if(!validQuotaTypes.contains(quotaType)) {
258 Utils.croak("Specify a valid quota type from :" + validQuotaTypes);
262 return quotaTypes;
266 * Utility function that creates directory.
268 * @param dir Directory path
269 * @return File object of directory.
271 public static File createDir(String dir) {
272 // create outdir
273 File directory = null;
274 if(dir != null) {
275 directory = new File(dir);
276 if(!(directory.exists() || directory.mkdir())) {
277 Utils.croak("Can't find or create directory " + dir);
280 return directory;
284 * Utility function that fetches system store definitions
286 * @return The map container that maps store names to store definitions
288 public static Map<String, StoreDefinition> getSystemStoreDefs() {
289 Map<String, StoreDefinition> sysStoreDefMap = Maps.newHashMap();
290 List<StoreDefinition> storesDefs = SystemStoreConstants.getAllSystemStoreDefs();
291 for(StoreDefinition def: storesDefs) {
292 sysStoreDefMap.put(def.getName(), def);
294 return sysStoreDefMap;
298 * Utility function that fetches user defined store definitions
300 * @param adminClient An instance of AdminClient points to given cluster
301 * @param node Store definitions to fetch from
302 * @return The map container that maps store names to store definitions
304 public static Map<String, StoreDefinition> getUserStoreDefs(AdminClient adminClient, Node node) {
305 List<StoreDefinition> storeDefinitionList = adminClient.metadataMgmtOps.getRemoteStoreDefList(node.getId())
306 .getValue();
307 Map<String, StoreDefinition> storeDefinitionMap = Maps.newHashMap();
308 for(StoreDefinition storeDefinition: storeDefinitionList) {
309 storeDefinitionMap.put(storeDefinition.getName(), storeDefinition);
311 return storeDefinitionMap;
315 * Utility function that checks the execution state of the server by
316 * checking the state of {@link VoldemortState} <br>
318 * This function checks if all nodes of the cluster are in normal state (
319 * {@link VoldemortState#NORMAL_SERVER}).
321 * @param adminClient An instance of AdminClient points to given cluster
322 * @throws VoldemortException if any node is not in normal state
324 public static void checkServerInNormalState(AdminClient adminClient) {
325 checkServerInNormalState(adminClient, adminClient.getAdminClientCluster().getNodes());
329 * Utility function that checks the execution state of the server by
330 * checking the state of {@link VoldemortState} <br>
332 * This function checks if a node is in normal state (
333 * {@link VoldemortState#NORMAL_SERVER}).
335 * @param adminClient An instance of AdminClient points to given cluster
336 * @param node Node to be checked
337 * @throws VoldemortException if any node is not in normal state
339 public static void checkServerInNormalState(AdminClient adminClient, Node node) {
340 List<Node> nodes = Lists.newArrayList();
341 nodes.add(node);
342 checkServerInNormalState(adminClient, nodes);
346 * Utility function that checks the execution state of the server by
347 * checking the state of {@link VoldemortState} <br>
349 * This function checks if the nodes are in normal state (
350 * {@link VoldemortState#NORMAL_SERVER}).
352 * @param adminClient An instance of AdminClient points to given cluster
353 * @param nodes List of nodes to be checked
354 * @throws VoldemortException if any node is not in normal state
356 public static void checkServerInNormalState(AdminClient adminClient, Collection<Node> nodes) {
357 for(Node node: nodes) {
358 Versioned<String> versioned = adminClient.metadataMgmtOps.getRemoteMetadata(node.getId(),
359 MetadataStore.SERVER_STATE_KEY);
360 VoldemortState state = VoldemortState.valueOf(versioned.getValue());
361 if(!state.equals(VoldemortState.NORMAL_SERVER)) {
362 throw new VoldemortException("Cannot execute admin operation: " + node.getId()
363 + " (" + node.getHost()
364 + ") is not in normal state, but in "
365 + versioned.getValue());