View Javadoc

1   /**
2    *
3    * Licensed to the Apache Software Foundation (ASF) under one
4    * or more contributor license agreements.  See the NOTICE file
5    * distributed with this work for additional information
6    * regarding copyright ownership.  The ASF licenses this file
7    * to you under the Apache License, Version 2.0 (the
8    * "License"); you may not use this file except in compliance
9    * with the License.  You may obtain a copy of the License at
10   *
11   *     http://www.apache.org/licenses/LICENSE-2.0
12   *
13   * Unless required by applicable law or agreed to in writing, software
14   * distributed under the License is distributed on an "AS IS" BASIS,
15   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16   * See the License for the specific language governing permissions and
17   * limitations under the License.
18   */
19  package org.apache.hadoop.hbase.regionserver;
20  
21  import static org.junit.Assert.assertFalse;
22  import static org.junit.Assert.assertNull;
23  import static org.junit.Assert.assertTrue;
24  
25  import java.util.concurrent.Semaphore;
26  
27  import org.apache.commons.logging.Log;
28  import org.apache.commons.logging.LogFactory;
29  import org.apache.hadoop.hbase.*;
30  import org.apache.hadoop.hbase.testclassification.MediumTests;
31  import org.apache.hadoop.hbase.zookeeper.MasterAddressTracker;
32  import org.apache.hadoop.hbase.zookeeper.ZKUtil;
33  import org.apache.hadoop.hbase.zookeeper.ZooKeeperListener;
34  import org.apache.hadoop.hbase.zookeeper.ZooKeeperWatcher;
35  import org.junit.AfterClass;
36  import org.junit.BeforeClass;
37  import org.junit.Test;
38  import org.junit.Rule;
39  import org.junit.rules.TestName;
40  import org.junit.experimental.categories.Category;
41  
42  @Category(MediumTests.class)
43  public class TestMasterAddressTracker {
44    private static final Log LOG = LogFactory.getLog(TestMasterAddressTracker.class);
45  
46    private final static HBaseTestingUtility TEST_UTIL = new HBaseTestingUtility();
47  
48    @Rule
49    public TestName name = new TestName();
50  
51    @BeforeClass
52    public static void setUpBeforeClass() throws Exception {
53      TEST_UTIL.startMiniZKCluster();
54    }
55  
56    @AfterClass
57    public static void tearDownAfterClass() throws Exception {
58      TEST_UTIL.shutdownMiniZKCluster();
59    }
60  
61    @Test
62    public void testDeleteIfEquals() throws Exception {
63      final ServerName sn = ServerName.valueOf("localhost", 1234, System.currentTimeMillis());
64      final MasterAddressTracker addressTracker = setupMasterTracker(sn);
65      try {
66        assertFalse("shouldn't have deleted wrong master server.",
67            MasterAddressTracker.deleteIfEquals(addressTracker.getWatcher(), "some other string."));
68      } finally {
69        assertTrue("Couldn't clean up master",
70            MasterAddressTracker.deleteIfEquals(addressTracker.getWatcher(), sn.toString()));
71      }
72    }
73  
74    /**
75     * create an address tracker instance
76     * @param sn if not-null set the active master
77     */
78    private MasterAddressTracker setupMasterTracker(final ServerName sn)
79        throws Exception {
80      ZooKeeperWatcher zk = new ZooKeeperWatcher(TEST_UTIL.getConfiguration(),
81          name.getMethodName(), null);
82      ZKUtil.createAndFailSilent(zk, zk.baseZNode);
83  
84      // Should not have a master yet
85      MasterAddressTracker addressTracker = new MasterAddressTracker(zk, null);
86      addressTracker.start();
87      assertFalse(addressTracker.hasMaster());
88      zk.registerListener(addressTracker);
89  
90      // Use a listener to capture when the node is actually created
91      NodeCreationListener listener = new NodeCreationListener(zk, zk.getMasterAddressZNode());
92      zk.registerListener(listener);
93  
94      if (sn != null) {
95        LOG.info("Creating master node");
96        MasterAddressTracker.setMasterAddress(zk, zk.getMasterAddressZNode(), sn);
97  
98        // Wait for the node to be created
99        LOG.info("Waiting for master address manager to be notified");
100       listener.waitForCreation();
101       LOG.info("Master node created");
102     }
103     return addressTracker;
104   }
105 
106   /**
107    * Unit tests that uses ZooKeeper but does not use the master-side methods
108    * but rather acts directly on ZK.
109    * @throws Exception
110    */
111   @Test
112   public void testMasterAddressTrackerFromZK() throws Exception {
113     // Create the master node with a dummy address
114     final ServerName sn = ServerName.valueOf("localhost", 1234, System.currentTimeMillis());
115     final MasterAddressTracker addressTracker = setupMasterTracker(sn);
116     try {
117       assertTrue(addressTracker.hasMaster());
118       ServerName pulledAddress = addressTracker.getMasterAddress();
119       assertTrue(pulledAddress.equals(sn));
120     } finally {
121       assertTrue("Couldn't clean up master",
122           MasterAddressTracker.deleteIfEquals(addressTracker.getWatcher(), sn.toString()));
123     }
124   }
125 
126   @Test
127   public void testNoMaster() throws Exception {
128     final MasterAddressTracker addressTracker = setupMasterTracker(null);
129     assertFalse(addressTracker.hasMaster());
130     assertNull("should get null master when none active.", addressTracker.getMasterAddress());
131   }
132 
133   public static class NodeCreationListener extends ZooKeeperListener {
134     private static final Log LOG = LogFactory.getLog(NodeCreationListener.class);
135 
136     private Semaphore lock;
137     private String node;
138 
139     public NodeCreationListener(ZooKeeperWatcher watcher, String node) {
140       super(watcher);
141       lock = new Semaphore(0);
142       this.node = node;
143     }
144 
145     @Override
146     public void nodeCreated(String path) {
147       if(path.equals(node)) {
148         LOG.debug("nodeCreated(" + path + ")");
149         lock.release();
150       }
151     }
152 
153     public void waitForCreation() throws InterruptedException {
154       lock.acquire();
155     }
156   }
157 
158 }
159