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