Java tutorial
/** * * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.alibaba.wasp.client; import com.alibaba.wasp.ReadModel; import com.alibaba.wasp.WaspTestingUtility; import com.alibaba.wasp.fserver.OperationStatus; import com.alibaba.wasp.meta.TableSchemaCacheReader; import com.alibaba.wasp.plan.parser.druid.DruidParserTestUtil; import com.alibaba.wasp.util.ResultInHBasePrinter; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.hadoop.hbase.DoNotRetryIOException; import org.apache.hadoop.hbase.HConstants.OperationStatusCode; import org.apache.hadoop.hbase.util.Bytes; import org.apache.hadoop.hbase.util.Pair; import org.junit.After; import org.junit.AfterClass; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; import java.io.IOException; import java.util.HashMap; import java.util.List; import java.util.Map; import static org.junit.Assert.assertTrue; /** * Run tests that use the Wasp clients; {@link FClient} and * {@link com.alibaba.wasp.jdbc.Driver}. Sets up the wasp mini cluster once at * start and runs through all client tests. Each creates a table named for the * method and does its stuff against that. */ public class TestFromClientSide { final Log LOG = LogFactory.getLog(getClass()); private final static WaspTestingUtility TEST_UTIL = new WaspTestingUtility(); private static FClient client; public static final String TABLE_NAME = "TEST_TABLE"; public static final byte[] TABLE = Bytes.toBytes(TABLE_NAME); public static String sessionId; public static final String INSERT = "insert"; public static final String SELECT_FOR_INSERT = "selectForInsert"; public static final String UPDATE = "update"; public static final String SELECT_FOR_UPDATE = "selectForUpdate"; public static final String DELETE = "delete"; public static final String SELECT_FOR_DELETE = "selectForDelete"; public static final String INDEX_NAME = "test_index"; public static final int fetchSize = 20; @BeforeClass public static void setUpBeforeClass() throws Exception { WaspTestingUtility.adjustLogLevel(); TEST_UTIL.getConfiguration().setInt("wasp.client.retries.number", 3); TEST_UTIL.startMiniCluster(3); TableSchemaCacheReader.getInstance(TEST_UTIL.getConfiguration()).clearCache(); TEST_UTIL.createTable(TABLE); TEST_UTIL.getWaspAdmin().disableTable(TABLE); client = new FClient(TEST_UTIL.getConfiguration()); client.execute("create index " + INDEX_NAME + " on " + TABLE_NAME + "(column3);"); TEST_UTIL.getWaspAdmin().waitTableNotLocked(TABLE); TEST_UTIL.getWaspAdmin().enableTable(TABLE); } @AfterClass public static void tearDownAfterClass() throws Exception { TEST_UTIL.shutdownMiniCluster(); } @Before public void setUp() throws Exception { } @After public void tearDown() throws Exception { } @Test public void testCreateTable() throws IOException { String sql1 = "CREATE TABLE User2 {Required Int64 user_id; Required String name; } " + "primary key(user_id), entity group root, entity group key(user_id);"; Pair<String, Pair<Boolean, List<ExecuteResult>>> pair = client.execute(sql1, ReadModel.SNAPSHOT, fetchSize); sessionId = pair.getFirst(); assertTrue(pair.getSecond().getSecond().get(0).getStatus() .getOperationStatusCode() == OperationStatusCode.SUCCESS); } @Test public void testLoopCreateDropTable() throws IOException, InterruptedException { for (int i = 0; i < 3; i++) { String sql1 = "CREATE TABLE Test_Loop {Required Int64 user_id; Required String name; } " + "primary key(user_id), entity group root, entity group key(user_id);"; Pair<String, Pair<Boolean, List<ExecuteResult>>> pair = client.execute(sql1); assertTrue(pair.getSecond().getSecond().get(0).getStatus() .getOperationStatusCode() == OperationStatusCode.SUCCESS); TEST_UTIL.waitTableEnabled(Bytes.toBytes("Test_Loop"), 50000); TEST_UTIL.getWaspAdmin().disableTable("Test_Loop"); String sql2 = "DROP TABLE IF EXISTS Test_Loop"; pair = client.execute(sql2); TEST_UTIL.getWaspAdmin().waitTableNotLocked("Test_Loop".getBytes()); assertTrue(pair.getSecond().getSecond().get(0).getStatus() .getOperationStatusCode() == OperationStatusCode.SUCCESS); Thread.currentThread().sleep(5000); } String sql1 = "CREATE TABLE Test_Loop {Required Int64 user_id; Required String name; } " + "primary key(user_id), entity group root, entity group key(user_id);"; Pair<String, Pair<Boolean, List<ExecuteResult>>> pair = client.execute(sql1); assertTrue(pair.getSecond().getSecond().get(0).getStatus() .getOperationStatusCode() == OperationStatusCode.SUCCESS); TEST_UTIL.waitTableEnabled(Bytes.toBytes("Test_Loop"), 50000); Map<String, String> sqlGroup = new HashMap<String, String>(); sqlGroup.put(INSERT, "Insert into Test_Loop (user_id,name) values (1,'binlijin');"); sqlGroup.put(SELECT_FOR_INSERT, "select user_id,name from Test_Loop where user_id=1;"); testSqlGroupExecute(sqlGroup); } public static void waitTableEnabled(WaspAdmin admin, byte[] table, long timeoutMillis) throws InterruptedException, IOException { long startWait = System.currentTimeMillis(); while (!admin.isTableEnabled(table)) { assertTrue("Timed out waiting for table " + Bytes.toStringBinary(table), System.currentTimeMillis() - startWait < timeoutMillis); Thread.sleep(200); } } @Test public void testCreateTableAndIndex() throws Exception { byte[][] table = { Bytes.toBytes("User"), Bytes.toBytes("Photo") }; for (int i = 0; i < DruidParserTestUtil.SEED.length; i++) { String sql = DruidParserTestUtil.SEED[i]; Pair<String, Pair<Boolean, List<ExecuteResult>>> pair = client.execute(sql, ReadModel.SNAPSHOT, fetchSize); sessionId = pair.getFirst(); assertTrue(pair.getSecond().getSecond().get(0).getStatus() .getOperationStatusCode() == OperationStatusCode.SUCCESS); TEST_UTIL.waitTableAvailable(table[i]); } TEST_UTIL.getWaspAdmin().disableTable(table[1]); boolean isTableDisabled = TEST_UTIL.getWaspAdmin().isTableDisabled(table[1]); LOG.info(" ---------------- Photo isTableDisabled=" + isTableDisabled); for (String sql : DruidParserTestUtil.INDEX_SEED) { Pair<String, Pair<Boolean, List<ExecuteResult>>> pair = client.execute(sql, ReadModel.SNAPSHOT, fetchSize); TEST_UTIL.getWaspAdmin().waitTableNotLocked("Photo".getBytes()); sessionId = pair.getFirst(); assertTrue(pair.getSecond().getSecond().get(0).getStatus() .getOperationStatusCode() == OperationStatusCode.SUCCESS); } TEST_UTIL.getWaspAdmin().enableTable(table[1]); boolean isTableEnabled = TEST_UTIL.getWaspAdmin().isTableEnabled(table[1]); LOG.info(" ---------------- Photo isTableEnabled=" + isTableEnabled); } @Test public void testExecute() throws IOException { Pair<String, Pair<Boolean, List<ExecuteResult>>> pair = client.execute( "select column1,column2,column3 from " + TABLE_NAME + " where column1=1 and column2=2", ReadModel.CURRENT, fetchSize); sessionId = pair.getFirst(); assertTrue(pair.getSecond().getSecond().size() == 0); } /** * */ @Test public void testSqlExecute() throws IOException { String INSERT = "Insert into " + TABLE_NAME + "(column1,column2,column3) values (10,10,'binlijin');"; Pair<String, Pair<Boolean, List<ExecuteResult>>> insertRet = client.execute(INSERT); assertTrue(insertRet.getSecond().getSecond().get(0).getStatus() .getOperationStatusCode() == OperationStatusCode.SUCCESS); printTablesRs("testSqlExecute"); } @Test public void testGetSql() throws IOException { Map<String, String> sqlGroup = new HashMap<String, String>(); sqlGroup.put(INSERT, "Insert into " + TABLE_NAME + "(column1,column2,column3) values (0,1,'binlijin');"); sqlGroup.put(SELECT_FOR_INSERT, "select column1,column2,column3 from " + TABLE_NAME + " where column1=0 and column2=1;"); testSqlGroupExecute(sqlGroup); } @Test public void testScanSql() throws IOException { Map<String, String> sqlGroup = new HashMap<String, String>(); sqlGroup.put(INSERT, "Insert into " + TABLE_NAME + "(column1,column2,column3) values (1,0,'binlijin');"); sqlGroup.put(SELECT_FOR_INSERT, "select column1,column2,column3 from " + TABLE_NAME + " where column1=1 and column3='binlijin';"); testSqlGroupExecute(sqlGroup); } @Test public void testNormalSql() throws IOException { Map<String, String> sqlGroup = new HashMap<String, String>(); sqlGroup.put(INSERT, "Insert into " + TABLE_NAME + "(column1,column2,column3) values (1,2,'binlijin');"); sqlGroup.put(SELECT_FOR_INSERT, "select column1,column2,column3 from " + TABLE_NAME + " where column1=1 and column3='binlijin';"); sqlGroup.put(UPDATE, "UPDATE " + TABLE_NAME + " SET column3 = 'daizhiyuan' WHERE column1 = 1 and column2=2;"); sqlGroup.put(SELECT_FOR_UPDATE, "select column1,column2,column3 from " + TABLE_NAME + " where column1=1 and column3='daizhiyuan';"); sqlGroup.put(DELETE, "delete from " + TABLE_NAME + " where column1=1 and column2=2;"); sqlGroup.put(SELECT_FOR_DELETE, "select column1,column2,column3 from " + TABLE_NAME + " where column1=1 and column3='daizhiyuan';"); testSqlGroupExecute(sqlGroup); } @Test public void testMutilColSql() throws IOException { Map<String, String> sqlGroup = new HashMap<String, String>(); sqlGroup.put(INSERT, "Insert into " + TABLE_NAME + " (column1,column2,column3,column4,column5) values (1,54321,'luoshi',98.2,9999.9999);"); sqlGroup.put(SELECT_FOR_INSERT, "select column1,column2,column3,column4,column5 from " + TABLE_NAME + " where column1=1 and column3='luoshi';"); sqlGroup.put(UPDATE, "UPDATE " + TABLE_NAME + " SET column3 = 'tianwu' WHERE column1=1 and column2=54321;"); sqlGroup.put(SELECT_FOR_UPDATE, "select column1,column2,column3,column4,column5 from " + TABLE_NAME + " where column1=1 and column3='tianwu';"); sqlGroup.put(DELETE, "delete from " + TABLE_NAME + " where column1=1 and column2=54321;"); sqlGroup.put(SELECT_FOR_DELETE, "select column1,column2,column3,column4,column5 from " + TABLE_NAME + " where column1=1 and column3='tianwu';"); testSqlGroupExecute(sqlGroup); } @Test public void testSpecharsValue() throws IOException { Map<String, String> sqlGroup = new HashMap<String, String>(); sqlGroup.put(INSERT, "Insert into " + TABLE_NAME + " (column1,column2,column3) values (2,54321,'#luoshi');"); sqlGroup.put(SELECT_FOR_INSERT, "select column1,column2,column3 from " + TABLE_NAME + " where column1=2 and column3='#luoshi';"); testSqlGroupExecute(sqlGroup); } @Test(expected = DoNotRetryIOException.class) public void testInvalidDatatype() throws IOException { Map<String, String> sqlGroup = new HashMap<String, String>(); sqlGroup.put(INSERT, "Insert into " + TABLE_NAME + " (column1,column2,column3) values ('abc','def',123);"); sqlGroup.put(SELECT_FOR_INSERT, "select column1,column2,column3,column4,column5 from " + TABLE_NAME + " where column1='abc' and column3=123;"); testSqlGroupExecute(sqlGroup); } @Test(expected = IOException.class) public void testSelectNotUseIndex() throws IOException { Map<String, String> sqlGroup = new HashMap<String, String>(); sqlGroup.put(INSERT, "Insert into " + TABLE_NAME + " (column1,column2,column3) values (3,234,'abc');"); sqlGroup.put(SELECT_FOR_INSERT, "select column1,column2,column3,column4,column5 from " + TABLE_NAME + " where column2=234;"); testSqlGroupExecute(sqlGroup); } @Test(expected = IOException.class) public void testUpdateNotOnlyPK() throws IOException { Map<String, String> sqlGroup = new HashMap<String, String>(); sqlGroup.put(INSERT, "Insert into " + TABLE_NAME + " (column1,column2,column3,column4) values (4,234,'abc','bcd');"); sqlGroup.put(SELECT_FOR_INSERT, "select column1,column2,column3,column4,column5 from " + TABLE_NAME + " where column1=4 and column2=234 and column3='abc';"); sqlGroup.put(UPDATE, "UPDATE " + TABLE_NAME + " set column4='def' WHERE column1 = 4 and column2=234 and column4='bcd';"); testSqlGroupExecute(sqlGroup); } @Test(expected = IOException.class) public void testUpdatePK() throws IOException { Map<String, String> sqlGroup = new HashMap<String, String>(); sqlGroup.put(INSERT, "Insert into " + TABLE_NAME + " (column1,column2,column3) values (5,234,'abc');"); sqlGroup.put(SELECT_FOR_INSERT, "select column1,column2,column3,column4,column5 from " + TABLE_NAME + " where column1=5 and column2=234 and column3='abc';"); sqlGroup.put(UPDATE, "UPDATE " + TABLE_NAME + " set column1=6 WHERE column3='abc';"); testSqlGroupExecute(sqlGroup); } @Test(expected = IOException.class) public void testDeleteNotOnlyPK() throws IOException { Map<String, String> sqlGroup = new HashMap<String, String>(); sqlGroup.put(INSERT, "Insert into " + TABLE_NAME + " (column1,column2,column3) values (6,234,'abc');"); sqlGroup.put(SELECT_FOR_INSERT, "select column1,column2,column3,column4,column5 from " + TABLE_NAME + " where column1=6 and column2=234"); sqlGroup.put(DELETE, "DELETE FROM " + TABLE_NAME + " WHERE column3='abc';"); sqlGroup.put(SELECT_FOR_DELETE, "select column1,column2,column3,column4,column5 from " + TABLE_NAME + " where column1=6 and column2=234;"); testSqlGroupExecute(sqlGroup); } @Test // (expected = PrimaryKeyAlreadyExistsException.class) public void testInsertWithSomePK() throws IOException { Map<String, String> sqlGroup = new HashMap<String, String>(); sqlGroup.put(INSERT, "Insert into " + TABLE_NAME + " (column1,column2,column3) values (7,234,'abc');"); sqlGroup.put(SELECT_FOR_INSERT, "select column1,column2,column3,column4,column5 from " + TABLE_NAME + " where column1=7 and column3='abc';"); testSqlGroupExecute(sqlGroup); sqlGroup.clear(); String insert = "Insert into " + TABLE_NAME + " (column1,column2,column3) values (7,234,'def');"; Pair<String, Pair<Boolean, List<ExecuteResult>>> insertRet = client.execute(insert); OperationStatus operationStatus = insertRet.getSecond().getSecond().get(0).getStatus(); assertTrue(operationStatus.getOperationStatusCode() == OperationStatusCode.FAILURE); assertTrue(operationStatus.getExceptionClassname() .equals("com.alibaba.wasp.PrimaryKeyAlreadyExistsException")); } private void testSqlGroupExecute(Map<String, String> sqlGroup) throws IOException { String insert = sqlGroup.get(INSERT); if (insert != null) { Pair<String, Pair<Boolean, List<ExecuteResult>>> insertRet = client.execute(insert); assertTrue(insertRet.getSecond().getSecond().get(0).getStatus() .getOperationStatusCode() == OperationStatusCode.SUCCESS); printTablesRs("after " + INSERT); } String selectForInsert = sqlGroup.get(SELECT_FOR_INSERT); // test select if (selectForInsert != null) { Pair<String, Pair<Boolean, List<ExecuteResult>>> r1 = client.execute(selectForInsert, ReadModel.CURRENT, fetchSize); assertTrue(r1.getSecond().getSecond().size() > 0); } // test update String update = sqlGroup.get(UPDATE); if (update != null) { Pair<String, Pair<Boolean, List<ExecuteResult>>> updateRet = client.execute(update); assertTrue(updateRet.getSecond().getSecond().get(0).getStatus() .getOperationStatusCode() == OperationStatusCode.SUCCESS); printTablesRs("after " + UPDATE); } // test select String selectForUpdate = sqlGroup.get(SELECT_FOR_UPDATE); if (selectForUpdate != null) { Pair<String, Pair<Boolean, List<ExecuteResult>>> r2 = client.execute(selectForUpdate, ReadModel.CURRENT, fetchSize); assertTrue(r2.getSecond().getSecond().size() > 0); } // test delete String delete = sqlGroup.get(DELETE); if (delete != null) { Pair<String, Pair<Boolean, List<ExecuteResult>>> deleteRet = client.execute(delete); assertTrue(deleteRet.getSecond().getSecond().get(0).getStatus() .getOperationStatusCode() == OperationStatusCode.SUCCESS); printTablesRs("after " + DELETE); } String selectForDelete = sqlGroup.get(SELECT_FOR_DELETE); if (selectForDelete != null) { Pair<String, Pair<Boolean, List<ExecuteResult>>> r3 = client.execute(selectForDelete, ReadModel.CURRENT, fetchSize); assertTrue(r3.getSecond().getSecond().size() == 0); } } private void printTablesRs(String type) throws IOException { ResultInHBasePrinter.printTablesRs(type, TEST_UTIL.getConfiguration(), TABLE_NAME, INDEX_NAME, LOG); } @Test public void testQueryNext() throws IOException { String INSERT = "Insert into " + TABLE_NAME + "(column1,column2,column3) values (21,1,'binlijin');"; Pair<String, Pair<Boolean, List<ExecuteResult>>> insertRet = client.execute(INSERT); assertTrue(insertRet.getSecond().getSecond().get(0).getStatus() .getOperationStatusCode() == OperationStatusCode.SUCCESS); INSERT = "Insert into " + TABLE_NAME + "(column1,column2,column3) values (21,2,'binlijin');"; insertRet = client.execute(INSERT); assertTrue(insertRet.getSecond().getSecond().get(0).getStatus() .getOperationStatusCode() == OperationStatusCode.SUCCESS); String selectForInsert = "select column1,column2,column3 from " + TABLE_NAME + " where column1=21 and column3='binlijin'"; LOG.debug("************ first begin"); Pair<String, Pair<Boolean, List<ExecuteResult>>> r1 = client.execute(selectForInsert, ReadModel.CURRENT, 1); assertTrue(r1.getSecond().getSecond().size() > 0); String sessionId = r1.getFirst(); LOG.debug("************ second begin"); Pair<String, Pair<Boolean, List<ExecuteResult>>> r2 = client.next(sessionId); assertTrue(r2.getSecond().getSecond().size() > 0); } @Test public void testUpdateNullValueColumn() throws IOException { Map<String, String> sqlGroup = new HashMap<String, String>(); sqlGroup.put(INSERT, "Insert into " + TABLE_NAME + "(column1,column2,column3) values (1,2,'binlijin');"); sqlGroup.put(SELECT_FOR_INSERT, "select column1,column2,column3 from " + TABLE_NAME + " where column1=1 and column3='binlijin';"); sqlGroup.put(UPDATE, "UPDATE " + TABLE_NAME + " SET column8 = 'aaabbb' WHERE column1 = 1 and column2=2;"); sqlGroup.put(SELECT_FOR_UPDATE, "select column1,column2,column3,column8 from " + TABLE_NAME + " where column1=1 and column2=2;"); sqlGroup.put(DELETE, "delete from " + TABLE_NAME + " where column1=1 and column2=2;"); sqlGroup.put(SELECT_FOR_DELETE, "select column1,column2,column3,column8 from " + TABLE_NAME + " where column1=1 and column2=2;"); testSqlGroupExecute(sqlGroup); } }