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