diff --git a/src/main/java/org/apache/hadoop/hbase/regionserver/HRegion.java b/src/main/java/org/apache/hadoop/hbase/regionserver/HRegion.java index eaa02d1..b6e0e64 100644 --- a/src/main/java/org/apache/hadoop/hbase/regionserver/HRegion.java +++ b/src/main/java/org/apache/hadoop/hbase/regionserver/HRegion.java @@ -3030,7 +3030,6 @@ public class HRegion implements HeapSize { // , Writable{ * @throws IOException */ private void internalPut(Put put, UUID clusterId, boolean writeToWAL) throws IOException { - Map> familyMap = put.getFamilyMap(); WALEdit walEdit = new WALEdit(); /* run pre put hook outside of lock to avoid deadlock */ if (coprocessorHost != null) { @@ -3038,6 +3037,7 @@ public class HRegion implements HeapSize { // , Writable{ return; } } + Map> familyMap = put.getFamilyMap(); long now = EnvironmentEdgeManager.currentTimeMillis(); byte[] byteNow = Bytes.toBytes(now); diff --git a/src/test/java/org/apache/hadoop/hbase/coprocessor/SimpleRegionObserver.java b/src/test/java/org/apache/hadoop/hbase/coprocessor/SimpleRegionObserver.java index f587c2e..2b3ead0 100644 --- a/src/test/java/org/apache/hadoop/hbase/coprocessor/SimpleRegionObserver.java +++ b/src/test/java/org/apache/hadoop/hbase/coprocessor/SimpleRegionObserver.java @@ -109,8 +109,10 @@ public class SimpleRegionObserver extends BaseRegionObserver { // from external packages RegionCoprocessorEnvironment re = (RegionCoprocessorEnvironment)e; Leases leases = re.getRegionServerServices().getLeases(); - leases.createLease("x", null); - leases.cancelLease("x"); + if (leases != null) { + leases.createLease("x", null); + leases.cancelLease("x"); + } } @Override diff --git a/src/test/java/org/apache/hadoop/hbase/coprocessor/TestRegionObserverInterface.java b/src/test/java/org/apache/hadoop/hbase/coprocessor/TestRegionObserverInterface.java index 9d8f0fc..4218bf7 100644 --- a/src/test/java/org/apache/hadoop/hbase/coprocessor/TestRegionObserverInterface.java +++ b/src/test/java/org/apache/hadoop/hbase/coprocessor/TestRegionObserverInterface.java @@ -21,6 +21,7 @@ package org.apache.hadoop.hbase.coprocessor; import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; @@ -30,6 +31,9 @@ import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import java.util.Map; +import java.util.NavigableMap; +import java.util.TreeMap; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -46,9 +50,12 @@ import org.apache.hadoop.hbase.regionserver.InternalScanner; import org.apache.hadoop.hbase.regionserver.RegionCoprocessorHost; import org.apache.hadoop.hbase.regionserver.Store; import org.apache.hadoop.hbase.regionserver.StoreFile; +import org.apache.hadoop.hbase.regionserver.wal.HLog; +import org.apache.hadoop.hbase.regionserver.wal.WALEdit; import org.apache.hadoop.hbase.util.Bytes; import org.apache.hadoop.hbase.util.EnvironmentEdgeManager; import org.apache.hadoop.hbase.util.JVMClusterUtil; +import org.apache.hadoop.hbase.util.MockRegionServerServices; import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.Test; @@ -173,6 +180,48 @@ public class TestRegionObserverInterface { } @Test + public void testPutOverride() throws Exception { + byte[] tableName = Bytes.toBytes("testPutOverride"); + byte[] family = Bytes.toBytes("f"); + HTableDescriptor tableDesc = new HTableDescriptor(tableName); + HColumnDescriptor columnDesc = new HColumnDescriptor(family); + tableDesc.addFamily(columnDesc); + tableDesc.addCoprocessor(PutMultiplier.class.getName()); + Path tablePath = new Path("/tmp/" + tableName); + Path hlogPath = new Path("/tmp/hlog"); + Path oldPath = new Path("/tmp/.oldLogs"); + Configuration conf = util.getConfiguration(); + FileSystem fs = FileSystem.get(conf); + assertTrue(fs.mkdirs(tablePath)); + HLog hlog = new HLog(fs, hlogPath, oldPath, conf); + HRegion region = new HRegion(tablePath, hlog, fs, conf, + new HRegionInfo(tableName), tableDesc, new MockRegionServerServices()); + try { + region.initialize(); + + Put p = new Put(ROW); + p.add(family, A, Bytes.toBytes(1L)); + p.add(family, B, Bytes.toBytes(2L)); + p.add(family, C, Bytes.toBytes(3L)); + region.put(p); + + Get g = new Get(ROW); + Result result = region.get(g); + KeyValue kvA = result.getColumnLatest(family, A); + KeyValue kvB = result.getColumnLatest(family, B); + KeyValue kvC = result.getColumnLatest(family, C); + assertNotNull(kvA); + assertEquals(2L, Bytes.toLong(kvA.getValue())); + assertNotNull(kvB); + assertEquals(4L, Bytes.toLong(kvB.getValue())); + assertNotNull(kvC); + assertEquals(6L, Bytes.toLong(kvC.getValue())); + } finally { + region.close(); + } + } + + @Test public void testIncrementHook() throws IOException { byte[] tableName = TEST_TABLE; @@ -513,6 +562,30 @@ public class TestRegionObserverInterface { } } + /** + * Simple test RegionObserver that multiplies all cell values in the prePut() method by 2. + */ + public static final class PutMultiplier extends BaseRegionObserver { + @Override + public void prePut(ObserverContext e, Put put, WALEdit edit, + boolean writeToWAL) throws IOException { + NavigableMap> newFamilyMap = + new TreeMap>(Bytes.BYTES_COMPARATOR); + for (Map.Entry> entry : put.getFamilyMap().entrySet()) { + List newCells = new ArrayList(entry.getValue().size()); + for (KeyValue kv : entry.getValue()) { + // assumes that all cell values are longs + long value = Bytes.toLong(kv.getValue()); + byte[] newValue = Bytes.toBytes(value * 2); + newCells.add(new KeyValue(kv.getRow(), kv.getFamily(), kv.getQualifier(), + kv.getTimestamp(), newValue)); + } + newFamilyMap.put(entry.getKey(), newCells); + } + put.setFamilyMap(newFamilyMap); + } + } + private static byte [][] makeN(byte [] base, int n) { byte [][] ret = new byte[n][]; for(int i=0;i