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.jupiter.api.Assertions.assertNotNull; 021import static org.junit.jupiter.api.Assertions.assertTrue; 022 023import java.io.IOException; 024import java.util.Arrays; 025import java.util.List; 026import java.util.Optional; 027import org.apache.hadoop.hbase.Cell; 028import org.apache.hadoop.hbase.CellBuilderFactory; 029import org.apache.hadoop.hbase.CellBuilderType; 030import org.apache.hadoop.hbase.HBaseTestingUtil; 031import org.apache.hadoop.hbase.HConstants; 032import org.apache.hadoop.hbase.TableName; 033import org.apache.hadoop.hbase.client.Append; 034import org.apache.hadoop.hbase.client.Increment; 035import org.apache.hadoop.hbase.client.Result; 036import org.apache.hadoop.hbase.client.Row; 037import org.apache.hadoop.hbase.client.Table; 038import org.apache.hadoop.hbase.testclassification.CoprocessorTests; 039import org.apache.hadoop.hbase.testclassification.MediumTests; 040import org.apache.hadoop.hbase.util.Bytes; 041import org.junit.jupiter.api.AfterAll; 042import org.junit.jupiter.api.BeforeAll; 043import org.junit.jupiter.api.Tag; 044import org.junit.jupiter.api.Test; 045 046@Tag(CoprocessorTests.TAG) 047@Tag(MediumTests.TAG) 048public class TestIncrementAndAppendWithNullResult { 049 050 private static final HBaseTestingUtil util = new HBaseTestingUtil(); 051 private static final TableName TEST_TABLE = TableName.valueOf("test"); 052 private static final byte[] TEST_FAMILY = Bytes.toBytes("f1"); 053 private static final byte[] ROW_A = Bytes.toBytes("aaa"); 054 private static final byte[] qualifierCol1 = Bytes.toBytes("col1"); 055 private static Table table; 056 057 @BeforeAll 058 public static void setupBeforeClass() throws Exception { 059 util.getConfiguration().set(CoprocessorHost.REGION_COPROCESSOR_CONF_KEY, 060 MyObserver.class.getName()); 061 // reduce the retry count so as to speed up the test 062 util.getConfiguration().setInt(HConstants.HBASE_CLIENT_RETRIES_NUMBER, 2); 063 util.startMiniCluster(); 064 table = util.createTable(TEST_TABLE, TEST_FAMILY); 065 } 066 067 @AfterAll 068 public static void tearDownAfterClass() throws Exception { 069 util.shutdownMiniCluster(); 070 } 071 072 public static class MyObserver implements RegionCoprocessor, RegionObserver { 073 private static final Result TMP_RESULT = Result.create(Arrays 074 .asList(CellBuilderFactory.create(CellBuilderType.SHALLOW_COPY).setRow(Bytes.toBytes("row")) 075 .setFamily(Bytes.toBytes("family")).setQualifier(Bytes.toBytes("qualifier")) 076 .setType(Cell.Type.Put).setValue(Bytes.toBytes("value")).build())); 077 078 @Override 079 public Optional<RegionObserver> getRegionObserver() { 080 return Optional.of(this); 081 } 082 083 @Override 084 public Result preIncrementAfterRowLock( 085 ObserverContext<? extends RegionCoprocessorEnvironment> c, Increment increment) 086 throws IOException { 087 return TMP_RESULT; 088 } 089 090 @Override 091 public Result postIncrement(ObserverContext<? extends RegionCoprocessorEnvironment> c, 092 Increment increment, Result result) throws IOException { 093 return null; 094 } 095 096 @Override 097 public Result postAppend(ObserverContext<? extends RegionCoprocessorEnvironment> c, 098 Append append, Result result) { 099 return null; 100 } 101 102 @Override 103 public Result preAppendAfterRowLock(ObserverContext<? extends RegionCoprocessorEnvironment> c, 104 Append append) { 105 return TMP_RESULT; 106 } 107 } 108 109 @Test 110 public void testIncrement() throws Exception { 111 testAppend(new Increment(ROW_A).addColumn(TEST_FAMILY, qualifierCol1, 10L)); 112 testAppend( 113 new Increment(ROW_A).addColumn(TEST_FAMILY, qualifierCol1, 10L).setReturnResults(false)); 114 } 115 116 private void testAppend(Increment inc) throws Exception { 117 checkResult(table.increment(inc)); 118 List<Row> actions = Arrays.asList(inc, inc); 119 Object[] results = new Object[actions.size()]; 120 table.batch(actions, results); 121 checkResult(results); 122 } 123 124 @Test 125 public void testAppend() throws Exception { 126 testAppend(new Append(ROW_A).addColumn(TEST_FAMILY, qualifierCol1, Bytes.toBytes("value"))); 127 testAppend(new Append(ROW_A).addColumn(TEST_FAMILY, qualifierCol1, Bytes.toBytes("value")) 128 .setReturnResults(false)); 129 130 } 131 132 private void testAppend(Append append) throws Exception { 133 checkResult(table.append(append)); 134 List<Row> actions = Arrays.asList(append, append); 135 Object[] results = new Object[actions.size()]; 136 table.batch(actions, results); 137 checkResult(results); 138 } 139 140 private static void checkResult(Result r) { 141 checkResult(new Object[] { r }); 142 } 143 144 private static void checkResult(Object[] results) { 145 for (int i = 0; i != results.length; ++i) { 146 assertNotNull(results[i], "The result[" + i + "] should not be null"); 147 assertTrue(results[i] instanceof Result, "The result[" + i + "] should be Result type"); 148 assertTrue(((Result) results[i]).isEmpty(), "The result[" + i + "] should be empty"); 149 } 150 } 151}