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.junit.Assert.assertEquals; 021import static org.junit.Assert.assertTrue; 022import static org.junit.Assert.fail; 023 024import java.io.IOException; 025import org.apache.hadoop.hbase.CallDroppedException; 026import org.apache.hadoop.hbase.CallQueueTooBigException; 027import org.apache.hadoop.hbase.HBaseClassTestRule; 028import org.apache.hadoop.hbase.HBaseServerException; 029import org.apache.hadoop.hbase.testclassification.ClientTests; 030import org.apache.hadoop.hbase.testclassification.SmallTests; 031import org.junit.ClassRule; 032import org.junit.Test; 033import org.junit.experimental.categories.Category; 034 035@Category({ ClientTests.class, SmallTests.class }) 036public class TestRpcRetryingCallerImpl { 037 038 @ClassRule 039 public static final HBaseClassTestRule CLASS_RULE = 040 HBaseClassTestRule.forClass(TestRpcRetryingCallerImpl.class); 041 042 @Test 043 public void itUsesSpecialPauseForCQTBE() throws Exception { 044 itUsesSpecialPauseForServerOverloaded(CallQueueTooBigException.class); 045 } 046 047 @Test 048 public void itUsesSpecialPauseForCDE() throws Exception { 049 itUsesSpecialPauseForServerOverloaded(CallDroppedException.class); 050 } 051 052 private void itUsesSpecialPauseForServerOverloaded( 053 Class<? extends HBaseServerException> exceptionClass) throws Exception { 054 055 // the actual values don't matter here as long as they're distinct. 056 // the ThrowingCallable will assert that the passed in pause from RpcRetryingCallerImpl 057 // matches the specialPauseMillis 058 long pauseMillis = 1; 059 long specialPauseMillis = 2; 060 061 RpcRetryingCallerImpl<Void> caller = new RpcRetryingCallerImpl<>(pauseMillis, 062 specialPauseMillis, 2, RetryingCallerInterceptorFactory.NO_OP_INTERCEPTOR, 0, 0, null); 063 064 RetryingCallable<Void> callable = 065 new ThrowingCallable(CallQueueTooBigException.class, specialPauseMillis); 066 try { 067 caller.callWithRetries(callable, 5000); 068 fail("Expected " + exceptionClass.getSimpleName()); 069 } catch (RetriesExhaustedException e) { 070 assertTrue(e.getCause() instanceof HBaseServerException); 071 } 072 } 073 074 private static class ThrowingCallable implements RetryingCallable<Void> { 075 private final Class<? extends HBaseServerException> exceptionClass; 076 private final long specialPauseMillis; 077 078 public ThrowingCallable(Class<? extends HBaseServerException> exceptionClass, 079 long specialPauseMillis) { 080 this.exceptionClass = exceptionClass; 081 this.specialPauseMillis = specialPauseMillis; 082 } 083 084 @Override 085 public void prepare(boolean reload) throws IOException { 086 087 } 088 089 @Override 090 public void throwable(Throwable t, boolean retrying) { 091 092 } 093 094 @Override 095 public String getExceptionMessageAdditionalDetail() { 096 return null; 097 } 098 099 @Override 100 public long sleep(long pause, int tries) { 101 assertEquals(pause, specialPauseMillis); 102 return 0; 103 } 104 105 @Override 106 public Void call(int callTimeout) throws Exception { 107 throw exceptionClass.getConstructor().newInstance(); 108 } 109 } 110}