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 User user = UserProvider.instantiate(CONF).getCurrent(); 146 conn = new AsyncConnectionImpl(CONF, new DoNothingConnectionRegistry(CONF, user), "test", null, 147 user) { 148 149 @Override 150 CompletableFuture<MasterService.Interface> getMasterStub() { 151 return CompletableFuture.completedFuture(masterStub); 152 } 153 154 @Override 155 Interface getAdminStub(ServerName serverName) throws IOException { 156 return adminStub; 157 } 158 }; 159 } 160 161 private HBaseRpcController assertPriority(int priority) { 162 return argThat(new ArgumentMatcher<HBaseRpcController>() { 163 164 @Override 165 public boolean matches(HBaseRpcController controller) { 166 return controller.getPriority() == priority; 167 } 168 }); 169 } 170 171 @Test 172 public void testCreateNormalTable() { 173 conn.getAdmin() 174 .createTable(TableDescriptorBuilder.newBuilder(TableName.valueOf(name.getMethodName())) 175 .setColumnFamily(ColumnFamilyDescriptorBuilder.of("cf")).build()) 176 .join(); 177 verify(masterStub, times(1)).createTable(assertPriority(NORMAL_QOS), 178 any(CreateTableRequest.class), any()); 179 } 180 181 // a bit strange as we can not do this in production but anyway, just a client mock to confirm 182 // that we pass the correct priority 183 @Test 184 public void testCreateSystemTable() { 185 conn.getAdmin() 186 .createTable(TableDescriptorBuilder 187 .newBuilder(TableName.valueOf(SYSTEM_NAMESPACE_NAME_STR, name.getMethodName())) 188 .setColumnFamily(ColumnFamilyDescriptorBuilder.of("cf")).build()) 189 .join(); 190 verify(masterStub, times(1)).createTable(assertPriority(SYSTEMTABLE_QOS), 191 any(CreateTableRequest.class), any()); 192 } 193 194 // a bit strange as we can not do this in production but anyway, just a client mock to confirm 195 // that we pass the correct priority 196 @Test 197 public void testCreateMetaTable() { 198 conn.getAdmin().createTable(TableDescriptorBuilder.newBuilder(TableName.META_TABLE_NAME) 199 .setColumnFamily(ColumnFamilyDescriptorBuilder.of("cf")).build()).join(); 200 verify(masterStub, times(1)).createTable(assertPriority(SYSTEMTABLE_QOS), 201 any(CreateTableRequest.class), any()); 202 } 203 204 @Test 205 public void testShutdown() { 206 conn.getAdmin().shutdown().join(); 207 verify(masterStub, times(1)).shutdown(assertPriority(HIGH_QOS), any(ShutdownRequest.class), 208 any()); 209 } 210 211 @Test 212 public void testStopMaster() { 213 conn.getAdmin().stopMaster().join(); 214 verify(masterStub, times(1)).stopMaster(assertPriority(HIGH_QOS), any(StopMasterRequest.class), 215 any()); 216 } 217 218 @Test 219 public void testStopRegionServer() { 220 conn.getAdmin().stopRegionServer(ServerName.valueOf("rs", 16010, 12345)).join(); 221 verify(adminStub, times(1)).stopServer(assertPriority(HIGH_QOS), any(StopServerRequest.class), 222 any()); 223 } 224}