001/** 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software 013 * distributed under the License is distributed on an "AS IS" BASIS, 014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018package org.apache.hadoop.hbase.coprocessor; 019 020import java.io.IOException; 021import java.util.Optional; 022import junit.framework.TestCase; 023import org.apache.hadoop.conf.Configuration; 024import org.apache.hadoop.fs.Path; 025import org.apache.hadoop.hbase.Coprocessor; 026import org.apache.hadoop.hbase.HBaseClassTestRule; 027import org.apache.hadoop.hbase.HBaseTestingUtility; 028import org.apache.hadoop.hbase.HColumnDescriptor; 029import org.apache.hadoop.hbase.HRegionInfo; 030import org.apache.hadoop.hbase.HTableDescriptor; 031import org.apache.hadoop.hbase.TableName; 032import org.apache.hadoop.hbase.client.Durability; 033import org.apache.hadoop.hbase.client.Put; 034import org.apache.hadoop.hbase.regionserver.ChunkCreator; 035import org.apache.hadoop.hbase.regionserver.HRegion; 036import org.apache.hadoop.hbase.regionserver.MemStoreLABImpl; 037import org.apache.hadoop.hbase.regionserver.RegionCoprocessorHost; 038import org.apache.hadoop.hbase.regionserver.RegionServerServices; 039import org.apache.hadoop.hbase.testclassification.CoprocessorTests; 040import org.apache.hadoop.hbase.testclassification.SmallTests; 041import org.apache.hadoop.hbase.util.Bytes; 042import org.apache.hadoop.hbase.wal.WALEdit; 043import org.junit.ClassRule; 044import org.junit.experimental.categories.Category; 045import org.mockito.Mockito; 046 047@Category({CoprocessorTests.class, SmallTests.class}) 048public class TestRegionObserverStacking extends TestCase { 049 050 @ClassRule 051 public static final HBaseClassTestRule CLASS_RULE = 052 HBaseClassTestRule.forClass(TestRegionObserverStacking.class); 053 054 private static HBaseTestingUtility TEST_UTIL 055 = new HBaseTestingUtility(); 056 static final Path DIR = TEST_UTIL.getDataTestDir(); 057 058 public static class ObserverA implements RegionCoprocessor, RegionObserver { 059 long id; 060 061 @Override 062 public Optional<RegionObserver> getRegionObserver() { 063 return Optional.of(this); 064 } 065 066 @Override 067 public void postPut(final ObserverContext<RegionCoprocessorEnvironment> c, 068 final Put put, final WALEdit edit, 069 final Durability durability) 070 throws IOException { 071 id = System.currentTimeMillis(); 072 try { 073 Thread.sleep(10); 074 } catch (InterruptedException ex) { 075 } 076 } 077 } 078 079 public static class ObserverB implements RegionCoprocessor, RegionObserver { 080 long id; 081 082 @Override 083 public Optional<RegionObserver> getRegionObserver() { 084 return Optional.of(this); 085 } 086 087 @Override 088 public void postPut(final ObserverContext<RegionCoprocessorEnvironment> c, 089 final Put put, final WALEdit edit, 090 final Durability durability) 091 throws IOException { 092 id = System.currentTimeMillis(); 093 try { 094 Thread.sleep(10); 095 } catch (InterruptedException ex) { 096 } 097 } 098 } 099 100 public static class ObserverC implements RegionCoprocessor, RegionObserver { 101 long id; 102 103 @Override 104 public Optional<RegionObserver> getRegionObserver() { 105 return Optional.of(this); 106 } 107 108 @Override 109 public void postPut(final ObserverContext<RegionCoprocessorEnvironment> c, 110 final Put put, final WALEdit edit, 111 final Durability durability) 112 throws IOException { 113 id = System.currentTimeMillis(); 114 try { 115 Thread.sleep(10); 116 } catch (InterruptedException ex) { 117 } 118 } 119 } 120 121 HRegion initHRegion (byte [] tableName, String callingMethod, 122 Configuration conf, byte [] ... families) throws IOException { 123 HTableDescriptor htd = new HTableDescriptor(TableName.valueOf(tableName)); 124 for(byte [] family : families) { 125 htd.addFamily(new HColumnDescriptor(family)); 126 } 127 ChunkCreator.initialize(MemStoreLABImpl.CHUNK_SIZE_DEFAULT, false, 0, 0, 0, null); 128 HRegionInfo info = new HRegionInfo(htd.getTableName(), null, null, false); 129 Path path = new Path(DIR + callingMethod); 130 HRegion r = HBaseTestingUtility.createRegionAndWAL(info, path, conf, htd); 131 // this following piece is a hack. currently a coprocessorHost 132 // is secretly loaded at OpenRegionHandler. we don't really 133 // start a region server here, so just manually create cphost 134 // and set it to region. 135 RegionCoprocessorHost host = new RegionCoprocessorHost(r, 136 Mockito.mock(RegionServerServices.class), conf); 137 r.setCoprocessorHost(host); 138 return r; 139 } 140 141 public void testRegionObserverStacking() throws Exception { 142 byte[] ROW = Bytes.toBytes("testRow"); 143 byte[] TABLE = Bytes.toBytes(this.getClass().getSimpleName()); 144 byte[] A = Bytes.toBytes("A"); 145 byte[][] FAMILIES = new byte[][] { A } ; 146 147 Configuration conf = TEST_UTIL.getConfiguration(); 148 HRegion region = initHRegion(TABLE, getClass().getName(), 149 conf, FAMILIES); 150 RegionCoprocessorHost h = region.getCoprocessorHost(); 151 h.load(ObserverA.class, Coprocessor.PRIORITY_HIGHEST, conf); 152 h.load(ObserverB.class, Coprocessor.PRIORITY_USER, conf); 153 h.load(ObserverC.class, Coprocessor.PRIORITY_LOWEST, conf); 154 155 Put put = new Put(ROW); 156 put.addColumn(A, A, A); 157 region.put(put); 158 159 Coprocessor c = h.findCoprocessor(ObserverA.class.getName()); 160 long idA = ((ObserverA)c).id; 161 c = h.findCoprocessor(ObserverB.class.getName()); 162 long idB = ((ObserverB)c).id; 163 c = h.findCoprocessor(ObserverC.class.getName()); 164 long idC = ((ObserverC)c).id; 165 166 assertTrue(idA < idB); 167 assertTrue(idB < idC); 168 HBaseTestingUtility.closeRegionAndWAL(region); 169 } 170}