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 static org.junit.Assert.assertArrayEquals; 021import static org.junit.Assert.assertEquals; 022import static org.junit.Assert.assertTrue; 023 024import java.io.IOException; 025import java.util.Arrays; 026import java.util.List; 027import java.util.Map; 028import java.util.NavigableMap; 029import java.util.Optional; 030import org.apache.hadoop.hbase.Cell; 031import org.apache.hadoop.hbase.HBaseClassTestRule; 032import org.apache.hadoop.hbase.HBaseTestingUtil; 033import org.apache.hadoop.hbase.TableName; 034import org.apache.hadoop.hbase.client.Append; 035import org.apache.hadoop.hbase.client.Get; 036import org.apache.hadoop.hbase.client.Put; 037import org.apache.hadoop.hbase.client.Result; 038import org.apache.hadoop.hbase.client.Row; 039import org.apache.hadoop.hbase.client.Table; 040import org.apache.hadoop.hbase.io.TimeRange; 041import org.apache.hadoop.hbase.procedure2.RemoteProcedureDispatcher; 042import org.apache.hadoop.hbase.testclassification.CoprocessorTests; 043import org.apache.hadoop.hbase.testclassification.MediumTests; 044import org.apache.hadoop.hbase.util.Bytes; 045import org.apache.hadoop.hbase.util.EnvironmentEdgeManager; 046import org.apache.hadoop.hbase.util.ManualEnvironmentEdge; 047import org.junit.AfterClass; 048import org.junit.BeforeClass; 049import org.junit.ClassRule; 050import org.junit.Rule; 051import org.junit.Test; 052import org.junit.experimental.categories.Category; 053import org.junit.rules.TestName; 054 055@Category({ CoprocessorTests.class, MediumTests.class }) 056public class TestAppendTimeRange { 057 058 @ClassRule 059 public static final HBaseClassTestRule CLASS_RULE = 060 HBaseClassTestRule.forClass(TestAppendTimeRange.class); 061 062 @Rule 063 public TestName name = new TestName(); 064 065 private static final HBaseTestingUtil util = new HBaseTestingUtil(); 066 private static final ManualEnvironmentEdge mee = new ManualEnvironmentEdge(); 067 068 private static final byte[] TEST_FAMILY = Bytes.toBytes("f1"); 069 070 private static final byte[] ROW = Bytes.toBytes("aaa"); 071 072 private static final byte[] QUAL = Bytes.toBytes("col1"); 073 074 private static final byte[] VALUE = Bytes.toBytes("1"); 075 076 @BeforeClass 077 public static void setupBeforeClass() throws Exception { 078 util.getConfiguration().set(CoprocessorHost.REGION_COPROCESSOR_CONF_KEY, 079 MyObserver.class.getName()); 080 // Make general delay zero rather than default. Timing is off in this 081 // test that depends on an evironment edge that is manually moved forward. 082 util.getConfiguration().setInt(RemoteProcedureDispatcher.DISPATCH_DELAY_CONF_KEY, 0); 083 util.startMiniCluster(); 084 EnvironmentEdgeManager.injectEdge(mee); 085 } 086 087 @AfterClass 088 public static void tearDownAfterClass() throws Exception { 089 util.shutdownMiniCluster(); 090 } 091 092 public static class MyObserver implements RegionCoprocessor, RegionObserver { 093 private static TimeRange tr10 = null; 094 private static TimeRange tr2 = null; 095 096 @Override 097 public Optional<RegionObserver> getRegionObserver() { 098 return Optional.of(this); 099 } 100 101 @Override 102 public Result preAppend(final ObserverContext<? extends RegionCoprocessorEnvironment> e, 103 final Append append) throws IOException { 104 NavigableMap<byte[], List<Cell>> map = append.getFamilyCellMap(); 105 for (Map.Entry<byte[], List<Cell>> entry : map.entrySet()) { 106 for (Cell cell : entry.getValue()) { 107 String appendStr = 108 Bytes.toString(cell.getValueArray(), cell.getValueOffset(), cell.getValueLength()); 109 if (appendStr.equals("b")) { 110 tr10 = append.getTimeRange(); 111 } else if (appendStr.equals("c") && !append.getTimeRange().isAllTime()) { 112 tr2 = append.getTimeRange(); 113 } 114 } 115 } 116 return null; 117 } 118 } 119 120 @Test 121 public void testHTableInterfaceMethods() throws Exception { 122 try (Table table = util.createTable(TableName.valueOf(name.getMethodName()), TEST_FAMILY)) { 123 table.put(new Put(ROW).addColumn(TEST_FAMILY, QUAL, VALUE)); 124 long time = EnvironmentEdgeManager.currentTime(); 125 mee.setValue(time); 126 table.put(new Put(ROW).addColumn(TEST_FAMILY, QUAL, Bytes.toBytes("a"))); 127 checkRowValue(table, ROW, Bytes.toBytes("a")); 128 129 time = EnvironmentEdgeManager.currentTime(); 130 mee.setValue(time); 131 TimeRange range10 = TimeRange.between(1, time + 10); 132 table.append(new Append(ROW).addColumn(TEST_FAMILY, QUAL, Bytes.toBytes("b")) 133 .setTimeRange(range10.getMin(), range10.getMax())); 134 checkRowValue(table, ROW, Bytes.toBytes("ab")); 135 assertEquals(MyObserver.tr10.getMin(), range10.getMin()); 136 assertEquals(MyObserver.tr10.getMax(), range10.getMax()); 137 time = EnvironmentEdgeManager.currentTime(); 138 mee.setValue(time); 139 TimeRange range2 = TimeRange.between(1, time + 20); 140 List<Row> actions = Arrays.asList(new Row[] { 141 new Append(ROW).addColumn(TEST_FAMILY, QUAL, Bytes.toBytes("c")) 142 .setTimeRange(range2.getMin(), range2.getMax()), 143 new Append(ROW).addColumn(TEST_FAMILY, QUAL, Bytes.toBytes("c")) 144 .setTimeRange(range2.getMin(), range2.getMax()) }); 145 Object[] results1 = new Object[actions.size()]; 146 table.batch(actions, results1); 147 assertEquals(MyObserver.tr2.getMin(), range2.getMin()); 148 assertEquals(MyObserver.tr2.getMax(), range2.getMax()); 149 for (Object r2 : results1) { 150 assertTrue(r2 instanceof Result); 151 } 152 checkRowValue(table, ROW, Bytes.toBytes("abcc")); 153 } 154 } 155 156 private void checkRowValue(Table table, byte[] row, byte[] expectedValue) throws IOException { 157 Get get = new Get(row).addColumn(TEST_FAMILY, QUAL); 158 Result result = table.get(get); 159 byte[] actualValue = result.getValue(TEST_FAMILY, QUAL); 160 assertArrayEquals(expectedValue, actualValue); 161 } 162}