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.client;
019
020import static org.junit.Assert.assertArrayEquals;
021import static org.junit.Assert.assertEquals;
022
023import java.io.IOException;
024import java.util.concurrent.ExecutionException;
025import org.apache.commons.io.IOUtils;
026import org.apache.hadoop.hbase.HBaseClassTestRule;
027import org.apache.hadoop.hbase.HBaseTestingUtility;
028import org.apache.hadoop.hbase.TableName;
029import org.apache.hadoop.hbase.security.User;
030import org.apache.hadoop.hbase.testclassification.ClientTests;
031import org.apache.hadoop.hbase.testclassification.MediumTests;
032import org.apache.hadoop.hbase.util.Bytes;
033import org.junit.AfterClass;
034import org.junit.Before;
035import org.junit.BeforeClass;
036import org.junit.ClassRule;
037import org.junit.Rule;
038import org.junit.Test;
039import org.junit.experimental.categories.Category;
040import org.junit.rules.TestName;
041
042@Category({ MediumTests.class, ClientTests.class })
043public class TestAsyncTableNoncedRetry {
044
045  @ClassRule
046  public static final HBaseClassTestRule CLASS_RULE =
047      HBaseClassTestRule.forClass(TestAsyncTableNoncedRetry.class);
048
049  private static final HBaseTestingUtility TEST_UTIL = new HBaseTestingUtility();
050
051  private static TableName TABLE_NAME = TableName.valueOf("async");
052
053  private static byte[] FAMILY = Bytes.toBytes("cf");
054
055  private static byte[] QUALIFIER = Bytes.toBytes("cq");
056
057  private static byte[] VALUE = Bytes.toBytes("value");
058
059  private static AsyncConnection ASYNC_CONN;
060
061  private static long NONCE = 1L;
062
063  private static NonceGenerator NONCE_GENERATOR = new NonceGenerator() {
064
065    @Override
066    public long newNonce() {
067      return NONCE;
068    }
069
070    @Override
071    public long getNonceGroup() {
072      return 1L;
073    }
074  };
075
076  @Rule
077  public TestName testName = new TestName();
078
079  private byte[] row;
080
081  @BeforeClass
082  public static void setUpBeforeClass() throws Exception {
083    TEST_UTIL.startMiniCluster(1);
084    TEST_UTIL.createTable(TABLE_NAME, FAMILY);
085    TEST_UTIL.waitTableAvailable(TABLE_NAME);
086    AsyncRegistry registry = AsyncRegistryFactory.getRegistry(TEST_UTIL.getConfiguration());
087    ASYNC_CONN = new AsyncConnectionImpl(TEST_UTIL.getConfiguration(), registry,
088        registry.getClusterId().get(), User.getCurrent()) {
089
090      @Override
091      public NonceGenerator getNonceGenerator() {
092        return NONCE_GENERATOR;
093      }
094    };
095  }
096
097  @AfterClass
098  public static void tearDownAfterClass() throws Exception {
099    IOUtils.closeQuietly(ASYNC_CONN);
100    TEST_UTIL.shutdownMiniCluster();
101  }
102
103  @Before
104  public void setUp() throws IOException, InterruptedException {
105    row = Bytes.toBytes(testName.getMethodName().replaceAll("[^0-9A-Za-z]", "_"));
106    NONCE++;
107  }
108
109  @Test
110  public void testAppend() throws InterruptedException, ExecutionException {
111    AsyncTable<?> table = ASYNC_CONN.getTable(TABLE_NAME);
112    Result result = table.append(new Append(row).addColumn(FAMILY, QUALIFIER, VALUE)).get();
113    assertArrayEquals(VALUE, result.getValue(FAMILY, QUALIFIER));
114    result = table.append(new Append(row).addColumn(FAMILY, QUALIFIER, VALUE)).get();
115    // the second call should have no effect as we always generate the same nonce.
116    assertArrayEquals(VALUE, result.getValue(FAMILY, QUALIFIER));
117    result = table.get(new Get(row)).get();
118    assertArrayEquals(VALUE, result.getValue(FAMILY, QUALIFIER));
119  }
120
121  @Test
122  public void testIncrement() throws InterruptedException, ExecutionException {
123    AsyncTable<?> table = ASYNC_CONN.getTable(TABLE_NAME);
124    assertEquals(1L, table.incrementColumnValue(row, FAMILY, QUALIFIER, 1L).get().longValue());
125    // the second call should have no effect as we always generate the same nonce.
126    assertEquals(1L, table.incrementColumnValue(row, FAMILY, QUALIFIER, 1L).get().longValue());
127    Result result = table.get(new Get(row)).get();
128    assertEquals(1L, Bytes.toLong(result.getValue(FAMILY, QUALIFIER)));
129  }
130}