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.rest.client; 019 020import static org.junit.jupiter.api.Assertions.assertTrue; 021import static org.junit.jupiter.api.Assertions.fail; 022import static org.mockito.ArgumentMatchers.any; 023import static org.mockito.ArgumentMatchers.anyString; 024import static org.mockito.Mockito.mock; 025import static org.mockito.Mockito.times; 026import static org.mockito.Mockito.verify; 027import static org.mockito.Mockito.when; 028 029import java.io.IOException; 030import java.util.regex.Pattern; 031import org.apache.hadoop.conf.Configuration; 032import org.apache.hadoop.hbase.HBaseTestingUtil; 033import org.apache.hadoop.hbase.TableName; 034import org.apache.hadoop.hbase.client.TableDescriptorBuilder; 035import org.apache.hadoop.hbase.testclassification.RestTests; 036import org.apache.hadoop.hbase.testclassification.SmallTests; 037import org.apache.hadoop.hbase.util.Bytes; 038import org.apache.hadoop.hbase.util.EnvironmentEdgeManager; 039import org.junit.jupiter.api.BeforeEach; 040import org.junit.jupiter.api.Tag; 041import org.junit.jupiter.api.Test; 042 043/** 044 * Tests {@link RemoteAdmin} retries. 045 */ 046@Tag(RestTests.TAG) 047@Tag(SmallTests.TAG) 048public class TestRemoteAdminRetries { 049 050 private static final int SLEEP_TIME = 50; 051 private static final int RETRIES = 3; 052 private static final long MAX_TIME = SLEEP_TIME * (RETRIES - 1); 053 054 private static final HBaseTestingUtil TEST_UTIL = new HBaseTestingUtil(); 055 056 private RemoteAdmin remoteAdmin; 057 private Client client; 058 059 @BeforeEach 060 public void setup() throws Exception { 061 client = mock(Client.class); 062 Response response = new Response(509); 063 when(client.get(anyString(), anyString())).thenReturn(response); 064 when(client.delete(anyString())).thenReturn(response); 065 when(client.put(anyString(), anyString(), any())).thenReturn(response); 066 when(client.post(anyString(), anyString(), any())).thenReturn(response); 067 Configuration configuration = TEST_UTIL.getConfiguration(); 068 069 configuration.setInt("hbase.rest.client.max.retries", RETRIES); 070 configuration.setInt("hbase.rest.client.sleep", SLEEP_TIME); 071 072 remoteAdmin = new RemoteAdmin(client, TEST_UTIL.getConfiguration(), "MyTable"); 073 } 074 075 @Test 076 public void testFailingGetRestVersion() throws Exception { 077 testTimedOutGetCall(new CallExecutor() { 078 @Override 079 public void run() throws Exception { 080 remoteAdmin.getRestVersion(); 081 } 082 }); 083 } 084 085 @Test 086 public void testFailingGetClusterStatus() throws Exception { 087 testTimedOutGetCall(new CallExecutor() { 088 @Override 089 public void run() throws Exception { 090 remoteAdmin.getClusterStatus(); 091 } 092 }); 093 } 094 095 @Test 096 public void testFailingGetClusterVersion() throws Exception { 097 testTimedOutGetCall(new CallExecutor() { 098 @Override 099 public void run() throws Exception { 100 remoteAdmin.getClusterVersion(); 101 } 102 }); 103 } 104 105 @Test 106 public void testFailingGetTableAvailable() throws Exception { 107 testTimedOutCall(new CallExecutor() { 108 @Override 109 public void run() throws Exception { 110 remoteAdmin.isTableAvailable(Bytes.toBytes("TestTable")); 111 } 112 }); 113 } 114 115 @Test 116 public void testFailingCreateTable() throws Exception { 117 testTimedOutCall(new CallExecutor() { 118 @Override 119 public void run() throws Exception { 120 remoteAdmin 121 .createTable(TableDescriptorBuilder.newBuilder(TableName.valueOf("TestTable")).build()); 122 } 123 }); 124 verify(client, times(RETRIES)).put(anyString(), anyString(), any()); 125 } 126 127 @Test 128 public void testFailingDeleteTable() throws Exception { 129 testTimedOutCall(new CallExecutor() { 130 @Override 131 public void run() throws Exception { 132 remoteAdmin.deleteTable("TestTable"); 133 } 134 }); 135 verify(client, times(RETRIES)).delete(anyString()); 136 } 137 138 @Test 139 public void testFailingGetTableList() throws Exception { 140 testTimedOutGetCall(new CallExecutor() { 141 @Override 142 public void run() throws Exception { 143 remoteAdmin.getTableList(); 144 } 145 }); 146 } 147 148 private void testTimedOutGetCall(CallExecutor callExecutor) throws Exception { 149 testTimedOutCall(callExecutor); 150 verify(client, times(RETRIES)).get(anyString(), anyString()); 151 } 152 153 private void testTimedOutCall(CallExecutor callExecutor) throws Exception { 154 long start = EnvironmentEdgeManager.currentTime(); 155 try { 156 callExecutor.run(); 157 fail("should be timeout exception!"); 158 } catch (IOException e) { 159 assertTrue(Pattern.matches(".*MyTable.*timed out", e.toString())); 160 } 161 assertTrue((EnvironmentEdgeManager.currentTime() - start) > MAX_TIME); 162 } 163 164 private interface CallExecutor { 165 void run() throws Exception; 166 } 167}