View Javadoc

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.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    protected IntegrationTestingUtility util;
49    protected ChaosMonkey monkey;
50    protected String monkeyToUse;
51    protected Properties monkeyProps;
52    protected boolean noClusterCleanUp = false;
53    private String tableName = "ChaosMonkeyRunner.tableName";
54    private String familyName = "ChaosMonkeyRunner.familyName";
55  
56    @Override
57    public void addOptions() {
58      addOptWithArg("m", MONKEY_LONG_OPT, "Which chaos monkey to run");
59      addOptWithArg(CHAOS_MONKEY_PROPS, "The properties file for specifying chaos "
60          + "monkey properties.");
61      addOptWithArg(TABLE_NAME_OPT, "Table name in the test to run chaos monkey against");
62      addOptWithArg(FAMILY_NAME_OPT, "Family name in the test to run chaos monkey against");
63    }
64  
65    @Override
66    protected void processOptions(CommandLine cmd) {
67      if (cmd.hasOption(MONKEY_LONG_OPT)) {
68        monkeyToUse = cmd.getOptionValue(MONKEY_LONG_OPT);
69      }
70      monkeyProps = new Properties();
71      if (cmd.hasOption(CHAOS_MONKEY_PROPS)) {
72        String chaosMonkeyPropsFile = cmd.getOptionValue(CHAOS_MONKEY_PROPS);
73        if (StringUtils.isNotEmpty(chaosMonkeyPropsFile)) {
74          try {
75            monkeyProps.load(this.getClass().getClassLoader()
76                .getResourceAsStream(chaosMonkeyPropsFile));
77          } catch (IOException e) {
78            LOG.warn(e);
79            System.exit(EXIT_FAILURE);
80          }
81        }
82      }
83      if (cmd.hasOption(TABLE_NAME_OPT)) {
84        this.tableName = cmd.getOptionValue(TABLE_NAME_OPT);
85      }
86      if (cmd.hasOption(FAMILY_NAME_OPT)) {
87        this.familyName = cmd.getOptionValue(FAMILY_NAME_OPT);
88      }
89    }
90  
91    @Override
92    protected int doWork() throws Exception {
93      setUpCluster();
94      getAndStartMonkey();
95      while (true) {// loop here until got killed
96        Thread.sleep(10000);
97      }
98    }
99  
100   public void setUpCluster() throws Exception {
101     util = getTestingUtil(getConf());
102     boolean isDistributed = isDistributedCluster(getConf());
103     if (isDistributed) {
104       util.createDistributedHBaseCluster();
105       util.checkNodeCount(1);// make sure there's at least 1 alive rs
106     } else {
107       throw new RuntimeException("ChaosMonkeyRunner must run againt a distributed cluster,"
108           + " please check and point to the right configuration dir");
109     }
110     this.setConf(util.getConfiguration());
111   }
112 
113   private boolean isDistributedCluster(Configuration conf) {
114     return conf.getBoolean(HConstants.CLUSTER_DISTRIBUTED, false);
115   }
116 
117   public void getAndStartMonkey() throws Exception {
118     util = getTestingUtil(getConf());
119     MonkeyFactory fact = MonkeyFactory.getFactory(monkeyToUse);
120     if (fact == null) {
121       fact = getDefaultMonkeyFactory();
122     }
123     monkey =
124         fact.setUtil(util).setTableName(getTablename()).setProperties(monkeyProps)
125             .setColumnFamilies(getColumnFamilies()).build();
126     monkey.start();
127   }
128 
129   protected IntegrationTestingUtility getTestingUtil(Configuration conf) {
130     if (this.util == null) {
131       if (conf == null) {
132         this.util = new IntegrationTestingUtility();
133         this.setConf(util.getConfiguration());
134       } else {
135         this.util = new IntegrationTestingUtility(conf);
136       }
137     }
138     return util;
139   }
140 
141   protected MonkeyFactory getDefaultMonkeyFactory() {
142     // Run with slow deterministic monkey by default
143     return MonkeyFactory.getFactory(MonkeyFactory.SLOW_DETERMINISTIC);
144   }
145 
146   public TableName getTablename() {
147     return TableName.valueOf(tableName);
148   }
149 
150   protected Set<String> getColumnFamilies() {
151     return Sets.newHashSet(familyName);
152   }
153 
154   public static void main(String[] args) throws Exception {
155     Configuration conf = HBaseConfiguration.create();
156     IntegrationTestingUtility.setUseDistributedCluster(conf);
157     int ret = ToolRunner.run(conf, new ChaosMonkeyRunner(), args);
158     System.exit(ret);
159   }
160 
161 }