1   /**
2    * Copyright 2011 The Apache Software Foundation
3    *
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *     http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing, software
15   * distributed under the License is distributed on an "AS IS" BASIS,
16   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17   * See the License for the specific language governing permissions and
18   * limitations under the License.
19   */
20  package org.apache.hadoop.hbase.regionserver.wal;
21  
22  import java.util.ArrayList;
23  import java.util.List;
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.util.Bytes;
32  import org.junit.After;
33  import org.junit.Before;
34  import org.junit.BeforeClass;
35  import org.junit.Test;
36  import org.junit.experimental.categories.Category;
37  
38  import static org.junit.Assert.*;
39  
40  /**
41   * Test that the actions are called while playing with an HLog
42   */
43  @Category(SmallTests.class)
44  public class TestWALActionsListener {
45    protected static final Log LOG = LogFactory.getLog(TestWALActionsListener.class);
46  
47    private final static HBaseTestingUtility TEST_UTIL =
48        new HBaseTestingUtility();
49  
50    private final static byte[] SOME_BYTES =  Bytes.toBytes("t");
51    private static FileSystem fs;
52    private static Path oldLogDir;
53    private static Path logDir;
54    private static Configuration conf;
55  
56    @BeforeClass
57    public static void setUpBeforeClass() throws Exception {
58      conf = TEST_UTIL.getConfiguration();
59      conf.setInt("hbase.regionserver.maxlogs", 5);
60      fs = FileSystem.get(conf);
61      oldLogDir = new Path(TEST_UTIL.getDataTestDir(),
62          HConstants.HREGION_OLDLOGDIR_NAME);
63      logDir = new Path(TEST_UTIL.getDataTestDir(),
64          HConstants.HREGION_LOGDIR_NAME);
65    }
66  
67    @Before
68    public void setUp() throws Exception {
69      fs.delete(logDir, true);
70      fs.delete(oldLogDir, 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      DummyWALActionsListener laterobserver = new DummyWALActionsListener();
89      HLog hlog = new HLog(fs, logDir, oldLogDir, conf, list, null);
90      HRegionInfo hri = new HRegionInfo(SOME_BYTES,
91               SOME_BYTES, SOME_BYTES, false);
92  
93      for (int i = 0; i < 20; i++) {
94        byte[] b = Bytes.toBytes(i+"");
95        KeyValue kv = new KeyValue(b,b,b);
96        WALEdit edit = new WALEdit();
97        edit.add(kv);
98        HTableDescriptor htd = new HTableDescriptor();
99        htd.addFamily(new HColumnDescriptor(b));
100 
101       HLogKey key = new HLogKey(b,b, 0, 0, HConstants.DEFAULT_CLUSTER_ID);
102       hlog.append(hri, key, edit, htd, true);
103       if (i == 10) {
104         hlog.registerWALActionsListener(laterobserver);
105       }
106       if (i % 2 == 0) {
107         hlog.rollWriter();
108       }
109     }
110 
111     hlog.close();
112     hlog.closeAndDelete();
113 
114     assertEquals(11, observer.preLogRollCounter);
115     assertEquals(11, observer.postLogRollCounter);
116     assertEquals(5, laterobserver.preLogRollCounter);
117     assertEquals(5, laterobserver.postLogRollCounter);
118     assertEquals(2, observer.closedCount);
119   }
120 
121 
122   /**
123    * Just counts when methods are called
124    */
125   static class DummyWALActionsListener implements WALActionsListener {
126     public int preLogRollCounter = 0;
127     public int postLogRollCounter = 0;
128     public int closedCount = 0;
129 
130     @Override
131     public void preLogRoll(Path oldFile, Path newFile) {
132       preLogRollCounter++;
133     }
134 
135     @Override
136     public void postLogRoll(Path oldFile, Path newFile) {
137       postLogRollCounter++;
138     }
139 
140     @Override
141     public void preLogArchive(Path oldFile, Path newFile) {
142       // Not interested
143     }
144 
145     @Override
146     public void postLogArchive(Path oldFile, Path newFile) {
147       // Not interested
148     }
149 
150     @Override
151     public void logRollRequested() {
152       // Not interested
153     }
154 
155     @Override
156     public void visitLogEntryBeforeWrite(HRegionInfo info, HLogKey logKey,
157         WALEdit logEdit) {
158       // Not interested
159 
160     }
161 
162     @Override
163     public void logCloseRequested() {
164       closedCount++;
165     }
166 
167     public void visitLogEntryBeforeWrite(HTableDescriptor htd, HLogKey logKey, WALEdit logEdit) {
168       //To change body of implemented methods use File | Settings | File Templates.
169     }
170 
171   }
172 
173   @org.junit.Rule
174   public org.apache.hadoop.hbase.ResourceCheckerJUnitRule cu =
175     new org.apache.hadoop.hbase.ResourceCheckerJUnitRule();
176 }
177