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.wal;
20  
21  import java.util.ArrayList;
22  import java.util.List;
23  
24  import org.apache.commons.logging.Log;
25  import org.apache.commons.logging.LogFactory;
26  import org.apache.hadoop.conf.Configuration;
27  import org.apache.hadoop.fs.FileSystem;
28  import org.apache.hadoop.fs.Path;
29  import org.apache.hadoop.hbase.HBaseTestingUtility;
30  import org.apache.hadoop.hbase.HColumnDescriptor;
31  import org.apache.hadoop.hbase.HConstants;
32  import org.apache.hadoop.hbase.HRegionInfo;
33  import org.apache.hadoop.hbase.HTableDescriptor;
34  import org.apache.hadoop.hbase.KeyValue;
35  import org.apache.hadoop.hbase.TableName;
36  import org.apache.hadoop.hbase.regionserver.MultiVersionConcurrencyControl;
37  import org.apache.hadoop.hbase.testclassification.SmallTests;
38  import org.apache.hadoop.hbase.util.Bytes;
39  import org.apache.hadoop.hbase.util.FSUtils;
40  import org.apache.hadoop.hbase.wal.WALFactory;
41  import org.apache.hadoop.hbase.wal.WAL;
42  import org.apache.hadoop.hbase.wal.WALKey;
43  import org.junit.After;
44  import org.junit.Before;
45  import org.junit.BeforeClass;
46  import org.junit.Test;
47  import org.junit.experimental.categories.Category;
48  
49  import static org.junit.Assert.*;
50  
51  /**
52   * Test that the actions are called while playing with an WAL
53   */
54  @Category(SmallTests.class)
55  public class TestWALActionsListener {
56    private static final Log LOG = LogFactory.getLog(TestWALActionsListener.class);
57  
58    private final static HBaseTestingUtility TEST_UTIL =
59        new HBaseTestingUtility();
60  
61    private final static byte[] SOME_BYTES =  Bytes.toBytes("t");
62    private static Configuration conf;
63    private static Path rootDir;
64    private static Path walRootDir;
65    private static FileSystem fs;
66    private static FileSystem walFs;
67  
68    @BeforeClass
69    public static void setUpBeforeClass() throws Exception {
70      conf = TEST_UTIL.getConfiguration();
71      conf.setInt("hbase.regionserver.maxlogs", 5);
72      rootDir = TEST_UTIL.createRootDir();
73      walRootDir = TEST_UTIL.createWALRootDir();
74      fs = FSUtils.getRootDirFileSystem(conf);
75      walFs = FSUtils.getWALFileSystem(conf);
76    }
77  
78    @Before
79    public void setUp() throws Exception {
80      fs.delete(rootDir, true);
81      walFs.delete(new Path(walRootDir, HConstants.HREGION_LOGDIR_NAME), true);
82      walFs.delete(new Path(walRootDir, HConstants.HREGION_OLDLOGDIR_NAME), true);
83    }
84  
85    @After
86    public void tearDown() throws Exception {
87      setUp();
88    }
89  
90    /**
91     * Add a bunch of dummy data and roll the logs every two insert. We
92     * should end up with 10 rolled files (plus the roll called in
93     * the constructor). Also test adding a listener while it's running.
94     */
95    @Test
96    public void testActionListener() throws Exception {
97      DummyWALActionsListener observer = new DummyWALActionsListener();
98      List<WALActionsListener> list = new ArrayList<WALActionsListener>();
99      list.add(observer);
100     final WALFactory wals = new WALFactory(conf, list, "testActionListener");
101     DummyWALActionsListener laterobserver = new DummyWALActionsListener();
102     HRegionInfo hri = new HRegionInfo(TableName.valueOf(SOME_BYTES),
103              SOME_BYTES, SOME_BYTES, false);
104     final WAL wal = wals.getWAL(hri.getEncodedNameAsBytes(), hri.getTable().getNamespace());
105     MultiVersionConcurrencyControl mvcc = new MultiVersionConcurrencyControl();
106     for (int i = 0; i < 20; i++) {
107       byte[] b = Bytes.toBytes(i+"");
108       KeyValue kv = new KeyValue(b,b,b);
109       WALEdit edit = new WALEdit();
110       edit.add(kv);
111       HTableDescriptor htd = new HTableDescriptor();
112       htd.addFamily(new HColumnDescriptor(b));
113 
114       final long txid = wal.append(htd, hri, new WALKey(hri.getEncodedNameAsBytes(),
115           TableName.valueOf(b), 0, mvcc), edit, true);
116       wal.sync(txid);
117       if (i == 10) {
118         wal.registerWALActionsListener(laterobserver);
119       }
120       if (i % 2 == 0) {
121         wal.rollWriter();
122       }
123     }
124 
125     wal.close();
126 
127     assertEquals(11, observer.preLogRollCounter);
128     assertEquals(11, observer.postLogRollCounter);
129     assertEquals(5, laterobserver.preLogRollCounter);
130     assertEquals(5, laterobserver.postLogRollCounter);
131     assertEquals(1, observer.closedCount);
132   }
133 
134 
135   /**
136    * Just counts when methods are called
137    */
138   public static class DummyWALActionsListener extends WALActionsListener.Base {
139     public int preLogRollCounter = 0;
140     public int postLogRollCounter = 0;
141     public int closedCount = 0;
142 
143     @Override
144     public void preLogRoll(Path oldFile, Path newFile) {
145       preLogRollCounter++;
146     }
147 
148     @Override
149     public void postLogRoll(Path oldFile, Path newFile) {
150       postLogRollCounter++;
151     }
152 
153     @Override
154     public void logCloseRequested() {
155       closedCount++;
156     }
157   }
158 
159 }
160