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.assertEquals;
22  import static org.junit.Assert.assertFalse;
23  import static org.junit.Assert.assertNull;
24  import static org.junit.Assert.assertTrue;
25  
26  import java.util.concurrent.Semaphore;
27  
28  import org.apache.commons.logging.Log;
29  import org.apache.commons.logging.LogFactory;
30  import org.apache.hadoop.hbase.*;
31  import org.apache.hadoop.hbase.testclassification.MediumTests;
32  import org.apache.hadoop.hbase.zookeeper.MasterAddressTracker;
33  import org.apache.hadoop.hbase.zookeeper.ZKUtil;
34  import org.apache.hadoop.hbase.zookeeper.ZooKeeperListener;
35  import org.apache.hadoop.hbase.zookeeper.ZooKeeperWatcher;
36  import org.junit.AfterClass;
37  import org.junit.BeforeClass;
38  import org.junit.Test;
39  import org.junit.Rule;
40  import org.junit.rules.TestName;
41  import org.junit.experimental.categories.Category;
42  
43  @Category(MediumTests.class)
44  public class TestMasterAddressTracker {
45    private static final Log LOG = LogFactory.getLog(TestMasterAddressTracker.class);
46  
47    private final static HBaseTestingUtility TEST_UTIL = new HBaseTestingUtility();
48  
49    @Rule
50    public TestName name = new TestName();
51  
52    @BeforeClass
53    public static void setUpBeforeClass() throws Exception {
54      TEST_UTIL.startMiniZKCluster();
55    }
56  
57    @AfterClass
58    public static void tearDownAfterClass() throws Exception {
59      TEST_UTIL.shutdownMiniZKCluster();
60    }
61  
62    @Test
63    public void testDeleteIfEquals() throws Exception {
64      final ServerName sn = ServerName.valueOf("localhost", 1234, System.currentTimeMillis());
65      final MasterAddressTracker addressTracker = setupMasterTracker(sn, 1772);
66      try {
67        assertFalse("shouldn't have deleted wrong master server.",
68            MasterAddressTracker.deleteIfEquals(addressTracker.getWatcher(), "some other string."));
69      } finally {
70        assertTrue("Couldn't clean up master",
71            MasterAddressTracker.deleteIfEquals(addressTracker.getWatcher(), sn.toString()));
72      }
73    }
74  
75    /**
76     * create an address tracker instance
77     * @param sn if not-null set the active master
78     * @param infoPort if there is an active master, set its info port.
79     */
80    private MasterAddressTracker setupMasterTracker(final ServerName sn, final int infoPort)
81        throws Exception {
82      ZooKeeperWatcher zk = new ZooKeeperWatcher(TEST_UTIL.getConfiguration(),
83          name.getMethodName(), null);
84      ZKUtil.createAndFailSilent(zk, zk.baseZNode);
85  
86      // Should not have a master yet
87      MasterAddressTracker addressTracker = new MasterAddressTracker(zk, null);
88      addressTracker.start();
89      assertFalse(addressTracker.hasMaster());
90      zk.registerListener(addressTracker);
91  
92      // Use a listener to capture when the node is actually created
93      NodeCreationListener listener = new NodeCreationListener(zk, zk.getMasterAddressZNode());
94      zk.registerListener(listener);
95  
96      if (sn != null) {
97        LOG.info("Creating master node");
98        MasterAddressTracker.setMasterAddress(zk, zk.getMasterAddressZNode(), sn, infoPort);
99  
100       // Wait for the node to be created
101       LOG.info("Waiting for master address manager to be notified");
102       listener.waitForCreation();
103       LOG.info("Master node created");
104     }
105     return addressTracker;
106   }
107 
108   /**
109    * Unit tests that uses ZooKeeper but does not use the master-side methods
110    * but rather acts directly on ZK.
111    * @throws Exception
112    */
113   @Test
114   public void testMasterAddressTrackerFromZK() throws Exception {
115     // Create the master node with a dummy address
116     final int infoPort = 1235;
117     final ServerName sn = ServerName.valueOf("localhost", 1234, System.currentTimeMillis());
118     final MasterAddressTracker addressTracker = setupMasterTracker(sn, infoPort);
119     try {
120       assertTrue(addressTracker.hasMaster());
121       ServerName pulledAddress = addressTracker.getMasterAddress();
122       assertTrue(pulledAddress.equals(sn));
123       assertEquals(infoPort, addressTracker.getMasterInfoPort());
124     } finally {
125       assertTrue("Couldn't clean up master",
126           MasterAddressTracker.deleteIfEquals(addressTracker.getWatcher(), sn.toString()));
127     }
128   }
129 
130 
131   @Test
132   public void testParsingNull() throws Exception {
133     assertNull("parse on null data should return null.", MasterAddressTracker.parse(null));
134   }
135 
136   @Test
137   public void testNoBackups() throws Exception {
138     final ServerName sn = ServerName.valueOf("localhost", 1234, System.currentTimeMillis());
139     final MasterAddressTracker addressTracker = setupMasterTracker(sn, 1772);
140     try {
141       assertEquals("Should receive 0 for backup not found.", 0,
142           addressTracker.getBackupMasterInfoPort(
143               ServerName.valueOf("doesnotexist.example.com", 1234, System.currentTimeMillis())));
144     } finally {
145       assertTrue("Couldn't clean up master",
146           MasterAddressTracker.deleteIfEquals(addressTracker.getWatcher(), sn.toString()));
147     }
148   }
149 
150   @Test
151   public void testNoMaster() throws Exception {
152     final MasterAddressTracker addressTracker = setupMasterTracker(null, 1772);
153     assertFalse(addressTracker.hasMaster());
154     assertNull("should get null master when none active.", addressTracker.getMasterAddress());
155     assertEquals("Should receive 0 for backup not found.", 0, addressTracker.getMasterInfoPort());
156   }
157 
158   public static class NodeCreationListener extends ZooKeeperListener {
159     private static final Log LOG = LogFactory.getLog(NodeCreationListener.class);
160 
161     private Semaphore lock;
162     private String node;
163 
164     public NodeCreationListener(ZooKeeperWatcher watcher, String node) {
165       super(watcher);
166       lock = new Semaphore(0);
167       this.node = node;
168     }
169 
170     @Override
171     public void nodeCreated(String path) {
172       if(path.equals(node)) {
173         LOG.debug("nodeCreated(" + path + ")");
174         lock.release();
175       }
176     }
177 
178     public void waitForCreation() throws InterruptedException {
179       lock.acquire();
180     }
181   }
182 
183 }
184