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.assertFalse;
022
023import java.net.URI;
024import java.util.ArrayList;
025import java.util.List;
026import org.apache.hadoop.conf.Configuration;
027import org.apache.hadoop.hbase.HBaseClassTestRule;
028import org.apache.hadoop.hbase.HBaseConfiguration;
029import org.apache.hadoop.hbase.HBaseTestingUtil;
030import org.apache.hadoop.hbase.HConstants;
031import org.apache.hadoop.hbase.TableName;
032import org.apache.hadoop.hbase.TableNameTestRule;
033import org.apache.hadoop.hbase.testclassification.ClientTests;
034import org.apache.hadoop.hbase.testclassification.MediumTests;
035import org.apache.hadoop.hbase.util.Bytes;
036import org.junit.After;
037import org.junit.AfterClass;
038import org.junit.Before;
039import org.junit.BeforeClass;
040import org.junit.ClassRule;
041import org.junit.Rule;
042import org.junit.Test;
043import org.junit.experimental.categories.Category;
044import org.junit.runner.RunWith;
045import org.junit.runners.Parameterized;
046import org.junit.runners.Parameterized.Parameter;
047import org.junit.runners.Parameterized.Parameters;
048import org.slf4j.Logger;
049import org.slf4j.LoggerFactory;
050
051/**
052 * Test basic read write operation with different {@link ConnectionRegistry} implementations.
053 */
054@RunWith(Parameterized.class)
055@Category({ MediumTests.class, ClientTests.class })
056public class TestBasicReadWriteWithDifferentConnectionRegistries {
057
058  @ClassRule
059  public static final HBaseClassTestRule CLASS_RULE =
060    HBaseClassTestRule.forClass(TestBasicReadWriteWithDifferentConnectionRegistries.class);
061
062  private static final Logger LOG =
063    LoggerFactory.getLogger(TestBasicReadWriteWithDifferentConnectionRegistries.class);
064
065  private static final HBaseTestingUtil UTIL = new HBaseTestingUtil();
066
067  public enum RegistryImpl {
068    ZK,
069    RPC,
070    ZK_URI,
071    RPC_URI
072  }
073
074  @Parameter
075  public RegistryImpl impl;
076
077  @Rule
078  public final TableNameTestRule name = new TableNameTestRule();
079
080  private byte[] FAMILY = Bytes.toBytes("family");
081
082  private Connection conn;
083
084  @Parameters(name = "{index}: impl={0}")
085  public static List<Object[]> data() {
086    List<Object[]> data = new ArrayList<Object[]>();
087    for (RegistryImpl impl : RegistryImpl.values()) {
088      data.add(new Object[] { impl });
089    }
090    return data;
091  }
092
093  @BeforeClass
094  public static void setUpBeforeClass() throws Exception {
095    UTIL.startMiniCluster();
096  }
097
098  @AfterClass
099  public static void tearDownAfterClass() throws Exception {
100    UTIL.shutdownMiniCluster();
101  }
102
103  @Before
104  public void setUp() throws Exception {
105    switch (impl) {
106      case ZK: {
107        Configuration conf = HBaseConfiguration.create();
108        conf.setClass(HConstants.CLIENT_CONNECTION_REGISTRY_IMPL_CONF_KEY,
109          ZKConnectionRegistry.class, ConnectionRegistry.class);
110        String quorum = UTIL.getZkCluster().getAddress().toString();
111        String path = UTIL.getConfiguration().get(HConstants.ZOOKEEPER_ZNODE_PARENT);
112        conf.set(HConstants.CLIENT_ZOOKEEPER_QUORUM, quorum);
113        conf.set(HConstants.ZOOKEEPER_ZNODE_PARENT, path);
114        LOG.info("connect to cluster through zk quorum={} and parent={}", quorum, path);
115        conn = ConnectionFactory.createConnection(conf);
116        break;
117      }
118      case RPC: {
119        Configuration conf = HBaseConfiguration.create();
120        conf.setClass(HConstants.CLIENT_CONNECTION_REGISTRY_IMPL_CONF_KEY,
121          RpcConnectionRegistry.class, ConnectionRegistry.class);
122        String bootstrapServers =
123          UTIL.getMiniHBaseCluster().getMaster().getServerName().getAddress().toString();
124        conf.set(RpcConnectionRegistry.BOOTSTRAP_NODES, bootstrapServers);
125        LOG.info("connect to cluster through rpc bootstrap servers={}", bootstrapServers);
126        conn = ConnectionFactory.createConnection(conf);
127        break;
128      }
129      case ZK_URI: {
130        String quorum = UTIL.getZkCluster().getAddress().toString();
131        String path = UTIL.getConfiguration().get(HConstants.ZOOKEEPER_ZNODE_PARENT);
132        URI connectionUri = new URI("hbase+zk://" + quorum + path);
133        LOG.info("connect to cluster through connection url: {}", connectionUri);
134        conn = ConnectionFactory.createConnection(connectionUri);
135        break;
136      }
137      case RPC_URI: {
138        URI connectionUri = new URI("hbase+rpc://"
139          + UTIL.getMiniHBaseCluster().getMaster().getServerName().getAddress().toString());
140        LOG.info("connect to cluster through connection url: {}", connectionUri);
141        conn = ConnectionFactory.createConnection(connectionUri);
142        break;
143      }
144      default:
145        throw new IllegalArgumentException("Unknown impl: " + impl);
146    }
147    try (Admin admin = conn.getAdmin()) {
148      admin.createTable(TableDescriptorBuilder.newBuilder(name.getTableName())
149        .setColumnFamily(ColumnFamilyDescriptorBuilder.of(FAMILY)).build());
150    }
151  }
152
153  @After
154  public void tearDown() throws Exception {
155    TableName tableName = name.getTableName();
156    try (Admin admin = conn.getAdmin()) {
157      admin.disableTable(tableName);
158      admin.deleteTable(tableName);
159    }
160    conn.close();
161  }
162
163  @Test
164  public void testReadWrite() throws Exception {
165    byte[] row = Bytes.toBytes("row");
166    byte[] qualifier = Bytes.toBytes("qualifier");
167    byte[] value = Bytes.toBytes("value");
168    try (Table table = conn.getTable(name.getTableName())) {
169      Put put = new Put(row).addColumn(FAMILY, qualifier, value);
170      table.put(put);
171      Result result = table.get(new Get(row));
172      assertArrayEquals(value, result.getValue(FAMILY, qualifier));
173      table.delete(new Delete(row));
174      assertFalse(table.exists(new Get(row)));
175    }
176  }
177}