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  
19  package org.apache.hadoop.hbase.chaos.util;
20  
21  import com.google.common.base.Preconditions;
22  import com.google.common.util.concurrent.ThreadFactoryBuilder;
23  import java.io.Closeable;
24  import java.io.IOException;
25  import java.util.concurrent.ExecutorService;
26  import java.util.concurrent.Executors;
27  import java.util.concurrent.TimeUnit;
28  
29  import org.apache.hadoop.conf.Configuration;
30  import org.apache.hadoop.hbase.HBaseConfiguration;
31  import org.apache.hadoop.hbase.IntegrationTestingUtility;
32  import org.slf4j.Logger;
33  import org.slf4j.LoggerFactory;
34  
35  /**
36   * This class can be used to control chaos monkeys life cycle.
37   */
38  public class Monkeys implements Closeable {
39    private static final Logger LOG = LoggerFactory.getLogger(Monkeys.class);
40  
41    private final Configuration conf;
42    private final ChaosMonkeyRunner monkeyRunner;
43    private final Runnable runner;
44    private final ExecutorService executor;
45  
46    public Monkeys() {
47      this(HBaseConfiguration.create());
48    }
49  
50    public Monkeys(Configuration conf) {
51      this.conf = Preconditions.checkNotNull(conf, "Should specify a configuration");
52      this.monkeyRunner = new ChaosMonkeyRunner();
53      this.runner = new Runnable() {
54        @Override public void run() {
55          try {
56            monkeyRunner.getAndStartMonkey();
57          } catch (Exception e) {
58            LOG.error("Exception occurred when running chaos monkeys: ", e);
59          }
60        }
61      };
62      this.executor = Executors.newSingleThreadExecutor(new ThreadFactoryBuilder()
63        .setDaemon(true).setNameFormat("ChaosMonkey").build());
64      IntegrationTestingUtility.setUseDistributedCluster(this.conf);
65    }
66  
67    public void addResource(Configuration otherConf) {
68      conf.addResource(otherConf);
69      monkeyRunner.setConf(conf);
70    }
71  
72    public void addResource(String otherConf) {
73      conf.addResource(otherConf);
74      monkeyRunner.setConf(conf);
75    }
76  
77    public void startChaos() {
78      executor.execute(runner);
79      LOG.info("Chaos monkeys are running.");
80    }
81  
82    public void stopChaos() {
83      monkeyRunner.stopRunner();
84      LOG.info("Chaos monkeys are stopped.");
85    }
86  
87    @Override
88    public void close() throws IOException {
89      executor.shutdown();
90      try {
91        // wait 10 seconds.
92        executor.awaitTermination(10, TimeUnit.SECONDS);
93      } catch (InterruptedException e) {
94        Thread.currentThread().interrupt();
95        LOG.warn("Interruption occurred while stopping chaos monkeys " + e);
96      }
97    }
98  }