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.apache.hadoop.hbase.HConstants.HIGH_QOS; 021import static org.apache.hadoop.hbase.HConstants.NORMAL_QOS; 022import static org.apache.hadoop.hbase.HConstants.SYSTEMTABLE_QOS; 023import static org.apache.hadoop.hbase.NamespaceDescriptor.SYSTEM_NAMESPACE_NAME_STR; 024import static org.mockito.ArgumentMatchers.any; 025import static org.mockito.ArgumentMatchers.argThat; 026import static org.mockito.Mockito.doAnswer; 027import static org.mockito.Mockito.mock; 028import static org.mockito.Mockito.times; 029import static org.mockito.Mockito.verify; 030 031import java.io.IOException; 032import java.util.concurrent.CompletableFuture; 033import org.apache.hadoop.conf.Configuration; 034import org.apache.hadoop.hbase.HBaseClassTestRule; 035import org.apache.hadoop.hbase.HBaseConfiguration; 036import org.apache.hadoop.hbase.ServerName; 037import org.apache.hadoop.hbase.TableName; 038import org.apache.hadoop.hbase.ipc.HBaseRpcController; 039import org.apache.hadoop.hbase.security.User; 040import org.apache.hadoop.hbase.security.UserProvider; 041import org.apache.hadoop.hbase.testclassification.ClientTests; 042import org.apache.hadoop.hbase.testclassification.SmallTests; 043import org.junit.Before; 044import org.junit.ClassRule; 045import org.junit.Rule; 046import org.junit.Test; 047import org.junit.experimental.categories.Category; 048import org.junit.rules.TestName; 049import org.mockito.ArgumentMatcher; 050import org.mockito.invocation.InvocationOnMock; 051import org.mockito.stubbing.Answer; 052 053import org.apache.hbase.thirdparty.com.google.protobuf.RpcCallback; 054 055import org.apache.hadoop.hbase.shaded.protobuf.generated.AdminProtos.AdminService; 056import org.apache.hadoop.hbase.shaded.protobuf.generated.AdminProtos.AdminService.Interface; 057import org.apache.hadoop.hbase.shaded.protobuf.generated.AdminProtos.StopServerRequest; 058import org.apache.hadoop.hbase.shaded.protobuf.generated.AdminProtos.StopServerResponse; 059import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.CreateTableRequest; 060import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.CreateTableResponse; 061import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.GetProcedureResultRequest; 062import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.GetProcedureResultResponse; 063import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.MasterService; 064import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.ShutdownRequest; 065import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.ShutdownResponse; 066import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.StopMasterRequest; 067import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.StopMasterResponse; 068 069/** 070 * Confirm that we will set the priority in {@link HBaseRpcController} for several admin operations. 071 */ 072@Category({ ClientTests.class, SmallTests.class }) 073public class TestAsyncAdminRpcPriority { 074 075 @ClassRule 076 public static final HBaseClassTestRule CLASS_RULE = 077 HBaseClassTestRule.forClass(TestAsyncAdminRpcPriority.class); 078 079 private static Configuration CONF = HBaseConfiguration.create(); 080 081 private MasterService.Interface masterStub; 082 083 private AdminService.Interface adminStub; 084 085 private AsyncConnection conn; 086 087 @Rule 088 public TestName name = new TestName(); 089 090 @Before 091 public void setUp() throws IOException { 092 masterStub = mock(MasterService.Interface.class); 093 adminStub = mock(AdminService.Interface.class); 094 doAnswer(new Answer<Void>() { 095 096 @Override 097 public Void answer(InvocationOnMock invocation) throws Throwable { 098 RpcCallback<GetProcedureResultResponse> done = invocation.getArgument(2); 099 done.run(GetProcedureResultResponse.newBuilder() 100 .setState(GetProcedureResultResponse.State.FINISHED).build()); 101 return null; 102 } 103 }).when(masterStub).getProcedureResult(any(HBaseRpcController.class), 104 any(GetProcedureResultRequest.class), any()); 105 doAnswer(new Answer<Void>() { 106 107 @Override 108 public Void answer(InvocationOnMock invocation) throws Throwable { 109 RpcCallback<CreateTableResponse> done = invocation.getArgument(2); 110 done.run(CreateTableResponse.newBuilder().setProcId(1L).build()); 111 return null; 112 } 113 }).when(masterStub).createTable(any(HBaseRpcController.class), any(CreateTableRequest.class), 114 any()); 115 doAnswer(new Answer<Void>() { 116 117 @Override 118 public Void answer(InvocationOnMock invocation) throws Throwable { 119 RpcCallback<ShutdownResponse> done = invocation.getArgument(2); 120 done.run(ShutdownResponse.getDefaultInstance()); 121 return null; 122 } 123 }).when(masterStub).shutdown(any(HBaseRpcController.class), any(ShutdownRequest.class), any()); 124 doAnswer(new Answer<Void>() { 125 126 @Override 127 public Void answer(InvocationOnMock invocation) throws Throwable { 128 RpcCallback<StopMasterResponse> done = invocation.getArgument(2); 129 done.run(StopMasterResponse.getDefaultInstance()); 130 return null; 131 } 132 }).when(masterStub).stopMaster(any(HBaseRpcController.class), any(StopMasterRequest.class), 133 any()); 134 135 doAnswer(new Answer<Void>() { 136 137 @Override 138 public Void answer(InvocationOnMock invocation) throws Throwable { 139 RpcCallback<StopServerResponse> done = invocation.getArgument(2); 140 done.run(StopServerResponse.getDefaultInstance()); 141 return null; 142 } 143 }).when(adminStub).stopServer(any(HBaseRpcController.class), any(StopServerRequest.class), 144 any()); 145 146 User user = UserProvider.instantiate(CONF).getCurrent(); 147 conn = 148 new AsyncConnectionImpl(CONF, new DoNothingConnectionRegistry(CONF, user), "test", user) { 149 150 @Override 151 CompletableFuture<MasterService.Interface> getMasterStub() { 152 return CompletableFuture.completedFuture(masterStub); 153 } 154 155 @Override 156 Interface getAdminStub(ServerName serverName) throws IOException { 157 return adminStub; 158 } 159 }; 160 } 161 162 private HBaseRpcController assertPriority(int priority) { 163 return argThat(new ArgumentMatcher<HBaseRpcController>() { 164 165 @Override 166 public boolean matches(HBaseRpcController controller) { 167 return controller.getPriority() == priority; 168 } 169 }); 170 } 171 172 @Test 173 public void testCreateNormalTable() { 174 conn.getAdmin() 175 .createTable(TableDescriptorBuilder.newBuilder(TableName.valueOf(name.getMethodName())) 176 .setColumnFamily(ColumnFamilyDescriptorBuilder.of("cf")).build()) 177 .join(); 178 verify(masterStub, times(1)).createTable(assertPriority(NORMAL_QOS), 179 any(CreateTableRequest.class), any()); 180 } 181 182 // a bit strange as we can not do this in production but anyway, just a client mock to confirm 183 // that we pass the correct priority 184 @Test 185 public void testCreateSystemTable() { 186 conn.getAdmin() 187 .createTable(TableDescriptorBuilder 188 .newBuilder(TableName.valueOf(SYSTEM_NAMESPACE_NAME_STR, name.getMethodName())) 189 .setColumnFamily(ColumnFamilyDescriptorBuilder.of("cf")).build()) 190 .join(); 191 verify(masterStub, times(1)).createTable(assertPriority(SYSTEMTABLE_QOS), 192 any(CreateTableRequest.class), any()); 193 } 194 195 // a bit strange as we can not do this in production but anyway, just a client mock to confirm 196 // that we pass the correct priority 197 @Test 198 public void testCreateMetaTable() { 199 conn.getAdmin().createTable(TableDescriptorBuilder.newBuilder(TableName.META_TABLE_NAME) 200 .setColumnFamily(ColumnFamilyDescriptorBuilder.of("cf")).build()).join(); 201 verify(masterStub, times(1)).createTable(assertPriority(SYSTEMTABLE_QOS), 202 any(CreateTableRequest.class), any()); 203 } 204 205 @Test 206 public void testShutdown() { 207 conn.getAdmin().shutdown().join(); 208 verify(masterStub, times(1)).shutdown(assertPriority(HIGH_QOS), any(ShutdownRequest.class), 209 any()); 210 } 211 212 @Test 213 public void testStopMaster() { 214 conn.getAdmin().stopMaster().join(); 215 verify(masterStub, times(1)).stopMaster(assertPriority(HIGH_QOS), any(StopMasterRequest.class), 216 any()); 217 } 218 219 @Test 220 public void testStopRegionServer() { 221 conn.getAdmin().stopRegionServer(ServerName.valueOf("rs", 16010, 12345)).join(); 222 verify(adminStub, times(1)).stopServer(assertPriority(HIGH_QOS), any(StopServerRequest.class), 223 any()); 224 } 225}