1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.hadoop.hbase.chaos.util;
19
20 import java.io.IOException;
21 import java.util.Properties;
22 import java.util.Set;
23
24 import org.apache.commons.cli.CommandLine;
25 import org.apache.commons.lang.StringUtils;
26 import org.apache.commons.logging.Log;
27 import org.apache.commons.logging.LogFactory;
28 import org.apache.hadoop.conf.Configuration;
29 import org.apache.hadoop.hbase.HBaseConfiguration;
30 import org.apache.hadoop.hbase.HConstants;
31 import org.apache.hadoop.hbase.IntegrationTestingUtility;
32 import org.apache.hadoop.hbase.TableName;
33 import org.apache.hadoop.hbase.chaos.factories.MonkeyFactory;
34 import org.apache.hadoop.hbase.chaos.monkies.ChaosMonkey;
35 import org.apache.hadoop.hbase.util.AbstractHBaseTool;
36 import org.apache.hadoop.util.ToolRunner;
37
38 import com.google.common.collect.Sets;
39
40 public class ChaosMonkeyRunner extends AbstractHBaseTool {
41 private static final Log LOG = LogFactory.getLog(ChaosMonkeyRunner.class);
42
43 public static final String MONKEY_LONG_OPT = "monkey";
44 public static final String CHAOS_MONKEY_PROPS = "monkeyProps";
45 public static final String TABLE_NAME_OPT = "tableName";
46 public static final String FAMILY_NAME_OPT = "familyName";
47
48 private static ChaosMonkeyRunner runner;
49
50 protected IntegrationTestingUtility util;
51 protected ChaosMonkey monkey;
52 protected String monkeyToUse;
53 protected Properties monkeyProps;
54 protected boolean noClusterCleanUp = false;
55 private String tableName = "ChaosMonkeyRunner.tableName";
56 private String familyName = "ChaosMonkeyRunner.familyName";
57 private volatile boolean stop = false;
58
59 @Override
60 public void addOptions() {
61 addOptWithArg("m", MONKEY_LONG_OPT, "Which chaos monkey to run");
62 addOptWithArg(CHAOS_MONKEY_PROPS, "The properties file for specifying chaos "
63 + "monkey properties.");
64 addOptWithArg(TABLE_NAME_OPT, "Table name in the test to run chaos monkey against");
65 addOptWithArg(FAMILY_NAME_OPT, "Family name in the test to run chaos monkey against");
66 }
67
68 @Override
69 protected void processOptions(CommandLine cmd) {
70 if (cmd.hasOption(MONKEY_LONG_OPT)) {
71 monkeyToUse = cmd.getOptionValue(MONKEY_LONG_OPT);
72 }
73 monkeyProps = new Properties();
74 if (cmd.hasOption(CHAOS_MONKEY_PROPS)) {
75 String chaosMonkeyPropsFile = cmd.getOptionValue(CHAOS_MONKEY_PROPS);
76 if (StringUtils.isNotEmpty(chaosMonkeyPropsFile)) {
77 try {
78 monkeyProps.load(this.getClass().getClassLoader()
79 .getResourceAsStream(chaosMonkeyPropsFile));
80 } catch (IOException e) {
81 LOG.warn(e);
82 System.exit(EXIT_FAILURE);
83 }
84 }
85 }
86 if (cmd.hasOption(TABLE_NAME_OPT)) {
87 this.tableName = cmd.getOptionValue(TABLE_NAME_OPT);
88 }
89 if (cmd.hasOption(FAMILY_NAME_OPT)) {
90 this.familyName = cmd.getOptionValue(FAMILY_NAME_OPT);
91 }
92 }
93
94 @Override
95 protected int doWork() throws Exception {
96 setUpCluster();
97 getAndStartMonkey();
98 while (!stop) {
99 Thread.sleep(10000);
100 }
101 return 0;
102 }
103
104 public static void stopRunner() {
105 runner.stop = true;
106 }
107
108 public void setUpCluster() throws Exception {
109 util = getTestingUtil(getConf());
110 boolean isDistributed = isDistributedCluster(getConf());
111 if (isDistributed) {
112 util.createDistributedHBaseCluster();
113 util.checkNodeCount(1);
114 } else {
115 throw new RuntimeException("ChaosMonkeyRunner must run againt a distributed cluster,"
116 + " please check and point to the right configuration dir");
117 }
118 this.setConf(util.getConfiguration());
119 }
120
121 private boolean isDistributedCluster(Configuration conf) {
122 return conf.getBoolean(HConstants.CLUSTER_DISTRIBUTED, false);
123 }
124
125 public void getAndStartMonkey() throws Exception {
126 util = getTestingUtil(getConf());
127 MonkeyFactory fact = MonkeyFactory.getFactory(monkeyToUse);
128 if (fact == null) {
129 fact = getDefaultMonkeyFactory();
130 }
131 monkey =
132 fact.setUtil(util).setTableName(getTablename()).setProperties(monkeyProps)
133 .setColumnFamilies(getColumnFamilies()).build();
134 monkey.start();
135 }
136
137 protected IntegrationTestingUtility getTestingUtil(Configuration conf) {
138 if (this.util == null) {
139 if (conf == null) {
140 this.util = new IntegrationTestingUtility();
141 this.setConf(util.getConfiguration());
142 } else {
143 this.util = new IntegrationTestingUtility(conf);
144 }
145 }
146 return util;
147 }
148
149 protected MonkeyFactory getDefaultMonkeyFactory() {
150
151 return MonkeyFactory.getFactory(MonkeyFactory.SLOW_DETERMINISTIC);
152 }
153
154 public TableName getTablename() {
155 return TableName.valueOf(tableName);
156 }
157
158 protected Set<String> getColumnFamilies() {
159 return Sets.newHashSet(familyName);
160 }
161
162
163
164
165
166
167 public static void main(String[] args) throws Exception {
168 Configuration conf = HBaseConfiguration.create();
169 String[] actualArgs = args;
170 if (args.length > 0 && "-c".equals(args[0])) {
171 int argCount = args.length - 2;
172 if (argCount < 0) {
173 throw new IllegalArgumentException("Missing path for -c parameter");
174 }
175
176 conf.addResource(args[1]);
177 actualArgs = new String[argCount];
178 System.arraycopy(args, 2, actualArgs, 0, argCount);
179 }
180 IntegrationTestingUtility.setUseDistributedCluster(conf);
181 runner = new ChaosMonkeyRunner();
182 int ret = ToolRunner.run(conf, runner, actualArgs);
183 System.exit(ret);
184 }
185
186 }