001/**
002 *
003 * Licensed to the Apache Software Foundation (ASF) under one
004 * or more contributor license agreements.  See the NOTICE file
005 * distributed with this work for additional information
006 * regarding copyright ownership.  The ASF licenses this file
007 * to you under the Apache License, Version 2.0 (the
008 * "License"); you may not use this file except in compliance
009 * with the License.  You may obtain a copy of the License at
010 *
011 *     http://www.apache.org/licenses/LICENSE-2.0
012 *
013 * Unless required by applicable law or agreed to in writing, software
014 * distributed under the License is distributed on an "AS IS" BASIS,
015 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
016 * See the License for the specific language governing permissions and
017 * limitations under the License.
018 */
019
020package org.apache.hadoop.hbase.coprocessor;
021
022import static org.junit.Assert.assertNotNull;
023import static org.junit.Assert.assertTrue;
024
025import java.io.IOException;
026import java.util.Arrays;
027import java.util.List;
028import java.util.Optional;
029import org.apache.hadoop.hbase.Cell;
030import org.apache.hadoop.hbase.CellBuilderFactory;
031import org.apache.hadoop.hbase.CellBuilderType;
032import org.apache.hadoop.hbase.HBaseClassTestRule;
033import org.apache.hadoop.hbase.HBaseTestingUtility;
034import org.apache.hadoop.hbase.HConstants;
035import org.apache.hadoop.hbase.TableName;
036import org.apache.hadoop.hbase.client.Append;
037import org.apache.hadoop.hbase.client.Increment;
038import org.apache.hadoop.hbase.client.Result;
039import org.apache.hadoop.hbase.client.Row;
040import org.apache.hadoop.hbase.client.Table;
041import org.apache.hadoop.hbase.testclassification.CoprocessorTests;
042import org.apache.hadoop.hbase.testclassification.MediumTests;
043import org.apache.hadoop.hbase.util.Bytes;
044import org.junit.AfterClass;
045import org.junit.BeforeClass;
046import org.junit.ClassRule;
047import org.junit.Test;
048import org.junit.experimental.categories.Category;
049
050@Category({CoprocessorTests.class, MediumTests.class})
051public class TestIncrementAndAppendWithNullResult {
052
053  @ClassRule
054  public static final HBaseClassTestRule CLASS_RULE =
055    HBaseClassTestRule.forClass(TestIncrementAndAppendWithNullResult.class);
056
057  private static final HBaseTestingUtility util = new HBaseTestingUtility();
058  private static final TableName TEST_TABLE = TableName.valueOf("test");
059  private static final byte[] TEST_FAMILY = Bytes.toBytes("f1");
060  private static final byte[] ROW_A = Bytes.toBytes("aaa");
061  private static final byte[] qualifierCol1 = Bytes.toBytes("col1");
062  private static Table table;
063
064  @BeforeClass
065  public static void setupBeforeClass() throws Exception {
066    util.getConfiguration().set(CoprocessorHost.REGION_COPROCESSOR_CONF_KEY,
067        MyObserver.class.getName());
068    // reduce the retry count so as to speed up the test
069    util.getConfiguration().setInt(HConstants.HBASE_CLIENT_RETRIES_NUMBER, 2);
070    util.startMiniCluster();
071    table = util.createTable(TEST_TABLE, TEST_FAMILY);
072  }
073
074  @AfterClass
075  public static void tearDownAfterClass() throws Exception {
076    util.shutdownMiniCluster();
077  }
078
079
080  public static class MyObserver implements RegionCoprocessor, RegionObserver {
081    private static final Result TMP_RESULT = Result.create(Arrays.asList(
082        CellBuilderFactory.create(CellBuilderType.SHALLOW_COPY)
083          .setRow(Bytes.toBytes("row"))
084          .setFamily(Bytes.toBytes("family"))
085          .setQualifier(Bytes.toBytes("qualifier"))
086          .setType(Cell.Type.Put)
087          .setValue(Bytes.toBytes("value"))
088          .build()));
089    @Override
090    public Optional<RegionObserver> getRegionObserver() {
091      return Optional.of(this);
092    }
093
094    @Override
095    public Result preIncrementAfterRowLock(ObserverContext<RegionCoprocessorEnvironment> c,
096        Increment increment) throws IOException {
097      return TMP_RESULT;
098    }
099
100    @Override
101    public Result postIncrement(ObserverContext<RegionCoprocessorEnvironment> c,
102      Increment increment, Result result) throws IOException {
103      return null;
104    }
105
106    @Override
107    public Result postAppend(ObserverContext<RegionCoprocessorEnvironment> c, Append append,
108        Result result) {
109      return null;
110    }
111
112    @Override
113    public Result preAppendAfterRowLock(ObserverContext<RegionCoprocessorEnvironment> c,
114        Append append) {
115      return TMP_RESULT;
116    }
117  }
118
119  @Test
120  public void testIncrement() throws Exception {
121    testAppend(new Increment(ROW_A).addColumn(TEST_FAMILY, qualifierCol1, 10L));
122    testAppend(new Increment(ROW_A).addColumn(TEST_FAMILY, qualifierCol1, 10L)
123              .setReturnResults(false));
124  }
125
126  private void testAppend(Increment inc) throws Exception {
127    checkResult(table.increment(inc));
128    List<Row> actions = Arrays.asList(inc, inc);
129    Object[] results = new Object[actions.size()];
130    table.batch(actions, results);
131    checkResult(results);
132  }
133
134  @Test
135  public void testAppend() throws Exception {
136    testAppend(new Append(ROW_A).addColumn(TEST_FAMILY, qualifierCol1,
137        Bytes.toBytes("value")));
138    testAppend(new Append(ROW_A).addColumn(TEST_FAMILY, qualifierCol1,
139        Bytes.toBytes("value")).setReturnResults(false));
140
141  }
142
143  private void testAppend(Append append) throws Exception {
144    checkResult(table.append(append));
145    List<Row> actions = Arrays.asList(append, append);
146    Object[] results = new Object[actions.size()];
147    table.batch(actions, results);
148    checkResult(results);
149  }
150
151  private static void checkResult(Result r) {
152    checkResult(new Object[]{r});
153  }
154
155  private static void checkResult(Object[] results) {
156    for (int i = 0; i != results.length; ++i) {
157      assertNotNull("The result[" + i + "] should not be null", results[i]);
158      assertTrue("The result[" + i + "] should be Result type", results[i] instanceof Result);
159      assertTrue("The result[" + i + "] shuold be empty", ((Result) results[i]).isEmpty());
160    }
161  }
162}